diff --git a/.workbuddy/memory/2026-07-18.md b/.workbuddy/memory/2026-07-18.md new file mode 100644 index 0000000..7e6c38e --- /dev/null +++ b/.workbuddy/memory/2026-07-18.md @@ -0,0 +1,165 @@ +# 2026-07-18 + +## ServerStack: 修复 Ubuntu 依赖安装的 libcurl 冲突 + +**问题**:在 Ubuntu 22.04 上跑 `installDepsUbuntu` 时出现 +- 图片 1: `libcurl4-gnutls-dev` 与 `libcurl4-openssl-dev` 互相 Conflicts,导致 + `E: Unable to correct problems, you have held broken packages`,整批依赖装不下去。 +- 图片 2: 大量老包被 `filter_pkglist` 跳过(`libpng12-0/-dev`、`libpng3`、 + `libidn11`、`libcloog-ppl1`、`sysv-rc`、`libjpeg62-turbo-dev`),虽然不报错, + 但每次都刷一堆 `Skip unavailable package: ...` 噪音。 + +**根因**:`lib/check_sw.sh` 的 `installDepsUbuntu`(line 119)的 pkgList +同时列了 `libcurl4-gnutls-dev` 和 `libcurl4-openssl-dev` 这两个互斥的 `-dev` 包。 +注释里说"Modern Debian/Ubuntu removed several legacy package names",但实际 +pkgList 自身并没有清理这些老包。 + +**修复**(`E:\workbuddy\ServerStack\lib\check_sw.sh`,仅改 Ubuntu 列表 line 119): +- 删掉 `libcurl4-gnutls-dev`(保留 `libcurl3-gnutls` 这个 runtime)。 + 依据:`modules/php/php-7.4.sh`、`php-8.0.sh`、`php-8.1.sh` 全部用 + `libcurl4-openssl-dev`,没有任何地方用 gnutls dev。 +- 顺手清理在新版 Ubuntu 上永远被 filter 跳过的死链包: + `libjpeg62-turbo-dev`、`libpng12-0/-dev`、`libpng3`、`libidn11`、 + `libcloog-ppl1`、`sysv-rc`。`libidn11-dev` 保留(仍可用),Debian 分支的 + 列表不动(不同发行版软件源不同)。 +- 加了一段说明注释,避免后人重新加回 `libcurl4-gnutls-dev`。 + +**验证**:`bash -n` 通过;图片 1 的冲突不会再出现,图片 2 的 Skip 噪音也基本清零。 + +## 补充:用户反馈同样的报错仍在出现 + +用户第二轮贴出**完全相同**的报错文本(含 `7.81.0-1ubuntu1.25` 版本号和 +`No VM guests are running outdated hypervisor (qemu)` 这条云 VM 特征消息)。 +排查结论: + +- 本地 `lib/check_sw.sh` 的 Ubuntu 列表(line 141)已经是干净的,没有 + `libcurl4-gnutls-dev`。 +- `backup/`、`runtime/` 都是空目录,全项目只有一份 `check_sw.sh`,没有其它副本。 +- 报错来自**远程 Ubuntu 22.04 服务器**上跑的旧版脚本,本地修改还没同步过去。 + +### 加防御层(`filter_pkglist()` 末尾,line 33-47) + +为了即使旧版 pkgList 被部署上去也不炸,在 `filter_pkglist()` 末尾加了一段 +互斥冲突消解:检测列表里同时有 `libcurl4-gnutls-dev` 和 `libcurl4-openssl-dev` +时,自动 sed 摘掉 gnutls dev 版,保留 openssl 版(PHP 各模块用的就是它), +`libcurl3-gnutls` runtime 不动。 + +隔离测试通过:`libcurl3-gnutls` 保留 / `libcurl4-openssl-dev` 保留 / +`libcurl4-gnutls-dev` 被移除。`bash -n` 语法通过。 + +### 给用户的行动项 + +需要把更新后的 `lib/check_sw.sh` 重新同步到服务器(rsync/scp/git pull 等), +然后重跑安装。同步后两层防护都会生效: +1. Ubuntu 列表源头已无 `libcurl4-gnutls-dev`(也不会再有 Skip 噪音)。 +2. 即便将来有人把互斥包加回去,`filter_pkglist` 会自动摘掉。 + +## 第三轮:修复"卡很久"的黑屏问题 + +用户反馈"在运行到此处时会卡很久"。分析 `install_pkgs()` 的卡顿来源: + +1. **批量 apt-get 遇冲突时静默求解**:apt 的依赖求解器遇到 `libcurl4-gnutls-dev` + vs `libcurl4-openssl-dev` 互斥时,会花 30s~2min 尝试各种组合才放弃,期间 + **无任何输出**,看起来像冻住。 +2. **逐包回退循环全静默**:批量失败后循环 ~60 个包,每个 `apt-get install` 输出 + 全 redirect 到 `/dev/null`,用户看到几分钟黑屏。 + +### 改动(`lib/check_sw.sh` 的 `install_pkgs()`,line 74-109) + +- 批量安装前再补一道冲突消解(防御纵深,防 filter_pkglist 被绕过或 pkgList + 被中间修改)。 +- 回退循环改成可见进度:每个包先 `printf` 包名(cyan,左对齐 40 列),再装, + 装完打 `OK`(绿)/`FAILED`(红)。屏幕永不空白。 +- 颜色变量复用 `lib/color.sh` 里已定义的 `CMSG/CSUCCESS/CFAILURE/CEND`。 +- `cat -v` 验证对齐和转义正确,`bash -n` 语法通过。 + +### 三层防护总览(都已在本地 `lib/check_sw.sh`) + +1. `installDepsUbuntu` 的 pkgList 源头已删 `libcurl4-gnutls-dev` + 死链包。 +2. `filter_pkglist()` 末尾自动消解 libcurl dev 互斥冲突。 +3. `install_pkgs()` 开头再消解一次 + 回退循环可见进度。 + +**用户必须做的**:把 `lib/check_sw.sh` 同步到服务器再重跑。当前服务器上跑的 +还是旧版,所以三轮都看到同样的报错。 + +## 第四轮:审视整个项目,杜绝静默安装 + +用户要求"不要静默安装, 要有相关提示"。全项目扫描结论: + +### 扫描发现 + +- 大多数 `make -j` / `./configure` **没有**被 `/dev/null` 吞输出(调用方 + `run_install()` 或 `Install_X | tee` 会显示并写日志),只是**缺起始提示**。 +- 唯一真正把安装输出吞掉的只有 `lib/check_sw.sh` 逐包回退的 + `apt-get ... >/dev/null 2>&1`(第三轮已改成可见进度,本轮再改成完全不吞)。 +- 下载环节 `lib/download.sh` 的 `Download_src()` 用 `wget -c`(无 `-q`),带进度,OK。 +- 所有模块安装统一经 `lib/loader.sh` 的 `run_install()`,是加统一提示的**单点**。 + +### 改动清单(7 个文件,`bash -n` 全通过) + +1. `lib/loader.sh` `run_install()`:加 `>> Installing: ` 横幅(带 module 路径)。 + 改这一处覆盖全部 47 个模块 + 主流程。 +2. `lib/check_sw.sh` `install_pkgs()` 回退循环:去掉 `>/dev/null`,每个包打印 + "Installing X ..." → "X installed OK / install FAILED",apt 下载进度可见。 +3. `lib/openssl.sh` `Install_openSSL()`:开头加 ">> Installing: openSSL ver"。 +4. `modules/web/jemalloc.sh` `Install_Jemalloc()`:开头加 ">> Installing: jemalloc ver"。 +5. `lib/check_sw.sh` `installDepsBySrc()`(ICU):开头加 ">> Installing: ICU ver"。 +6. `core/environment.sh` `prepare_install()`:`${PM} -y install wget gcc curl python` + 加提示 + `tee` 写日志(与上方 apt-get update 一致)。 +7. `core/os/init_Ubuntu.sh` / `init_Debian.sh`:iptables 安装两处 `apt-get` 加提示。 + +### 验证 + +- `grep 'apt-get.*install.*>/dev/null'` 全项目无匹配 → 再无静默 apt 安装。 +- 编译步骤输出仍可经 `| tee` 看到并落日志。 +- 收尾仍要提醒:所有改动需 `rsync`/`git pull` 到服务器才会生效。 + +## ServerStack: apt-get 依赖安装改为静默(-y) + 写日志 + +**需求变更**:上一轮把逐包回退改成屏幕逐行可见;这轮用户改口要 +「apt-get 静默安装(`-y`) + 输出安装日志」。 + +**改动**(`lib/check_sw.sh` 的 `install_pkgs()`): +- 统一 `export DEBIAN_FRONTEND=noninteractive`,apt 完全非交互(不再卡 debconf 提示)。 +- 批量安装:`apt-get --no-install-recommends -y install ${pkgList} >> runtime/install.log 2>&1`, + 屏幕只打印 `Installing dependency packages (... -> install.log)` 起始行 + + 成功后 `All dependency packages installed successfully.`。 +- 逐包回退:每个包同样 `apt-get -y ... >> install.log 2>&1`,屏幕只保留一行 + ` -> ... OK/FAILED`(printf 左对齐 40 列,OK 绿/FAILED 红)。 +- 日志路径 `local _log="${oneinstack_dir:-.}/runtime/install.log"`,与外层 + `installDepsUbuntu 2>&1 | tee` 同一文件;apt 详细输出直接追加、屏幕状态经 tee 落一份,无重复。 +- 同步更新函数顶部注释,去掉旧的 /dev/null 描述。`bash -n` 通过。 + +**设计要点**:屏幕保留简洁状态(可读、不黑屏),完整 apt 输出进 install.log(可 grep 排障)。 + +## 第五轮:修复安装摘要 URL 显示 http:/// (IPADDR 为空) + +**根因**:`IPADDR` 在 `core/environment.sh` 的 `prepare_install()` 由 `./lib/py/get_ipaddr.py` 获取, +该脚本靠 shebang `#!/usr/bin/env python` 启动;Ubuntu 22.04+ 只有 `python3` 无 `python` 命令, +且 base-tools 装的是不存在的 `python` 包、symlink 补救被 `~/.oneinstack` 判断限制, +导致脚本静默失败 → 标准输出空 → `IPADDR` 空 → 摘要 URL 变成 `http:///ocp.php` 等。 + +**修复**(仅 `environment.sh` + `bin/upgrade.sh`,`bash -n` 均通过): +1. 新增纯 shell 函数 `get_local_ipaddr()`(environment.sh),按 + `ip route get src` → `hostname -I` → `ip -o -4 addr show scope global` → `127.0.0.1` 回退,**不依赖 python**。 +2. `IPADDR=$(./lib/py/get_ipaddr.py)` 改为 `IPADDR=$(get_local_ipaddr)`。 +3. base-tools 安装 `python` → `python3`;`/usr/bin/python` 软链改**无条件**创建, + 让 get_public_ipaddr.py / get_ipaddr_state.py 也能跑。 +4. `bin/upgrade.sh` 独立入口同样加无条件 `python` 软链兜底。 + +**验证**:mock 命令测 `get_local_ipaddr` 三种场景均正确(有路由取 src / 无路由回退 hostname / 全无回退 127.0.0.1)。 +**注意**:改动仍在本地,需同步到服务器后重装/重跑 install 生效。 + +## 第五轮补充:VPC/私网场景让摘要 URL 改用公网 IP + +用户指出服务器是 **VPC 网络**。澄清:空 IP bug 与 VPC 无关(是 python 缺失);但 VPC 决定了 +"显示哪个 IP"——`ip route get` 在 VPC 取到的是**私网 RFC1918 地址**,从外部经公网 IP/EIP 访问时 +私网 URL 打不开。 + +**补充改动**(`core/environment.sh`): +1. 取 IP 顺序改为先 `PUBLIC_IPADDR=$(get_public_ipaddr.py)` 再 `IPADDR=$(get_local_ipaddr)`, + 让本地检测函数能引用已解析的公网 IP。 +2. `get_local_ipaddr()` 末尾加 case:`10.* / 172.16-31.* / 192.168.*` 私网段且 + `PUBLIC_IPADDR` 非空时,改用公网 IP;公网取不到则安全保留私网 IP。 + +**验证**:mock 四场景全过(VPC私网+公网→公网 / VPC私网+公网失败→私网 / 经典VM公网→公网 / 纯内网192.168+失败→192.168)。 diff --git a/.workbuddy/memory/2026-07-21.md b/.workbuddy/memory/2026-07-21.md new file mode 100644 index 0000000..8506683 --- /dev/null +++ b/.workbuddy/memory/2026-07-21.md @@ -0,0 +1,30 @@ +# 2026-07-21 + +## 升级脚本支持范围到 Debian 9-13 / Ubuntu 16-26 +- **根因**:`lib/check_sw.sh` 的 Debian 依赖 case 只列 `9|10|11|12`,Debian 13 会落入 `*` 分支被 `kill -9` 退出。 +- **改动**: + - `lib/check_sw.sh:151`:Debian case 标签 `9|10|11|12` → `9|10|11|12|13`,Debian 13 复用 12 的依赖列表;包名差异(如 libidn11 在新版移除)由 `filter_pkglist()` 按 `apt-cache policy` 动态兜底跳过。 + - 同步更新支持范围声明注释:`check_sw.sh:4`、`check_os.sh:5`、`README.md:14`、`docs/USAGE.md:3` 与 `:196`,由 "Debian 9+ / Ubuntu 16+" 改为 "Debian 9-13 / Ubuntu 16-26"。 +- **验证**:`bash -n` 两文件 OK;Debian 13 现落 `9|10|11|12|13` 分支;`check_os.sh` 门槛只查下限(`<9`/`<16`)无上限拦截,版本号解析 26.04→26、13→13 正确;`sslLibVer` 对 13/24/26 均 `ssl102`;Ubuntu 走 `installDepsUbuntu()` 无 case 拦截。 +- **边界(未处理)**:Ubuntu 24/26 系统 `libicu` 为新版本(74/76+),PHP 7.4 的 intl 扩展可能编译不兼容——属 PHP 模块级适配,本轮仅保证 OS 检测与依赖安装阶段不中途失败,未扩展 `libicu` 降级特例(原 `=~ ^22$` 仅覆盖 22.04)。 +- **仍须同步到服务器**:所有改动在本地 `E:\workbuddy\ServerStack\`,需 `rsync`/`git pull` 后重跑 `install.sh` 才生效。 + +## 限制 Ubuntu 24+ 只能装 PHP 8.x +- **根因**:Ubuntu 24+ 系统 `libicu` 为新版(74/76+),PHP 7.4(及 mphp 7.4)编译不兼容 intl 扩展。 +- **判断条件**:`Family==ubuntu && Ubuntu_ver>=24`(覆盖 24.04 / 25.x / 26.04)。Debian 不限;Ubuntu 22/23 仍允许 7.4。 +- **改动(4 文件,`bash -n` 全 OK)**: + - `core/menu.sh`:交互菜单在 Ubuntu 24+ 把选项 1(php-7.4) 标 `(unavailable on Ubuntu N+)`,选 1 时报错并重新选择。 + - `core/argument.sh`:命令行 `--php_option 1` / `--mphp_ver 74` 在 Ubuntu 24+ 直接 `exit 1` 报错。 + - `core/validator.sh`:校验阶段同样 `error_exit` 拒绝 7.4 / mphp 74。 + - `core/installer.sh`:分发处防御,`php_option=1` / `mphp_ver=74` 在 Ubuntu 24+ 跳过并提示(防绕过校验)。 +- **验证**:逻辑模拟各组合正确——Ubuntu 24/25/26 选 7.4 均拒;Ubuntu 22/23、Debian 13 仍允许;空 `Family` 变量有误杀防御(不限制)。 +- **仍须同步到服务器**才生效。 + +## 所有系统防火墙默认选 iptables +- **背景**:项目已裁剪为仅 Debian/Ubuntu(firewalld/ufw 已移除),iptables 是唯一的防火墙。原 `iptables_flag` 在交互模式需手动选、命令行模式需传 `--iptables` 才置 `y`,否则非交互安装就不装防火墙。 +- **改动(2 文件,`bash -n` 全 OK)**: + - `core/menu.sh`:交互提示默认 `y`(`[ -z "${iptables_flag}" ] && iptables_flag=y`,提示文案加 `(default y)`);用户仍可答 `n` 退出。 + - `core/argument.sh`:`parse_arguments` 末尾加 `iptables_flag=${iptables_flag:-y}`,非交互安装即使不传 `--iptables` 也默认启用;同时 `Show_Help` 文案改为 "Enable iptables (enabled by default on all systems)"。 + - 底层 `core/os/init_Ubuntu.sh` / `init_Debian.sh` 的 `if [ "${iptables_flag}" == 'y' ]` 分支不变,默认开启后所有系统(Debian 9-13 / Ubuntu 16-26)安装时均会装并配置 iptables。 +- **验证**:模拟四路径——非交互无 `--iptables`→y、带 `--iptables`→y、交互回车→y、交互答 n→n(退出仍生效)。 +- **仍须同步到服务器**才生效。 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md index f869959..3d7c42d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,210 @@ # ServerStack -lnmp安装包 \ No newline at end of file +ServerStack 是一键部署 Linux 服务器软件栈(LAMP / LNMP / LNMT 等)的自动化安装项目, +由原始 OneinStack 风格脚本经过**工程化结构重构(Project Restructure,非 Rewrite)**而来。 + +本次重构**只调整代码组织方式与目录结构**,不改动任何安装逻辑、安装顺序、命令行参数、 +配置格式、菜单与日志内容。原有的 `include/` 大杂烩被拆分为职责单一的目录树, +入口脚本与公共库、核心编排、软件模块彻底解耦。 + +> 历史使用说明请见 `docs/README.md`(上游原文档,未改动)。 + +> **软件裁剪(Software Trim)**:在重构基础上,进一步移除了 Tengine / OpenResty / Apache(仅保留 Nginx)、Percona 全系(仅保留 MySQL / MariaDB / PostgreSQL / MongoDB)、Memcached(仅保留 Redis)、OpenJDK 8/11(仅保留 Node.js / Python)、Tomcat 7–10(仅保留 phpMyAdmin)。相关安装 / 升级 / 下载 / 检测脚本与离线包清单均已同步裁剪;详见 `OFFLINE.md`。 + +> **系统裁剪(OS Trim)**:`lib/check_os.sh` 仅识别并支持 **Debian 9-13 / Ubuntu 16-26**(apt-get 系);RHEL/CentOS/Rocky/AlmaLinux/Oracle/Fedora/Amazon/openEuler 等 yum/dnf 系一律直接退出。相应地移除了 `installDepsRHEL`、`core/os/init_RHEL.sh` 以及 `init.sh` 的 rhel 分发。 + +--- + +## 1. 顶层目录结构 + +``` +ServerStack/ +├── bin/ # 入口脚本(用户直接执行的 CLI) +├── core/ # 核心流程编排(项目专属业务逻辑) +├── lib/ # 公共函数库(纯工具,无业务决策) +├── modules/ # 软件安装模块(按类别分区,高内聚) +├── services/ # systemd / init 单元文件 +├── config/ # 项目配置文件 +├── templates/ # 服务器 / vhost 配置模板 +├── src/ # 补丁 / 密钥 / 预置 tarball(原样保留) +├── scripts/ # 独立运维辅助脚本 +├── runtime/ # 运行时生成物(install.log、锁、状态标记) +├── logs/ # 运维日志(与 runtime 分离,便于轮转) +├── backup/ # 备份归档(backup.sh / db_bk.sh 写入) +├── docs/ # 文档 +├── tests/ # 测试(回归 / 冒烟脚本) +└── LICENSE +``` + +文件统计(15 个目录合计 270 文件,不含根目录文档/清单):`bin 9` `core 13` `lib 15` `modules 58` `services 6` +`config 2` `templates 19` `src 135` `scripts 7` `runtime 1` `logs 1` `backup 1` `docs 1` `tests 1`。 +(另含根目录 `LICENSE`、`README.md`、`OFFLINE.md`、`OFFLINE_MANIFEST.txt` 等文档/清单文件。) + +--- + +## 2. 各目录职责与边界 + +| 目录 | 职责 | 依赖关系 | 允许被谁调用 | 对外接口 | +|---|---|---|---|---| +| **bin/** | 用户 CLI 入口,只做最小 argv 解析后委托给 `core` | → core | 用户直接执行 | `install` / `uninstall` / `upgrade` / `vhost` / `addons` / `backup` / `backup_setup` / `pureftpd_vhost` / `reset_db_root_password` | +| **core/** | 项目专属编排:决定**安装顺序**与**流程**,不含具体软件安装码 | 依赖 lib(函数)+ modules(经 `run_install`) | 仅 bin/ | `main()` 及步骤函数 | +| **lib/** | 纯工具函数(日志 / 颜色 / 检测 / 下载),source 时无副作用、无业务判断 | 依赖 ∅(不向上依赖) | 任何人 | `load_common` / `log_*` / 颜色变量 / `check_*` | +| **modules/** | 单软件一文件,统一 `Install_X` 接口 | 仅依赖 lib;**禁止** source core(无向上依赖) | 仅经 `run_install` 被 core 调用 | `Install_X`(可选 Configure / Start) | +| **services/** | 静态单元文件 | 被 `service.sh` / `systemctl` 消费 | 系统 | 单元文件本身 | +| **config/** | 静态项目配置 | 被 `load_common` 消费 | core / lib | 配置项 | +| **templates/** | 静态服务器 / vhost 模板 | 安装时由 modules 渲染 | modules | 模板文件 | +| **src/** | 静态补丁 / 密钥 / 包 | 编译期被 modules 引用 | modules | 资产文件 | +| **scripts/** | 独立运维工具 | 可选 source lib | 用户 / backup 类脚本 | 独立命令 | +| **runtime/** / **logs/** / **backup/** | 生成物(日志 / 锁 / 备份) | 被框架写入 | 框架 | 文件 | +| **docs/** / **tests/** | 文档 / 测试(新增) | 无依赖 | 人类 / CI | — | + +### 依赖有向无环图(低耦合,无环) + +``` +bin → core → { lib, modules } +modules → lib +lib → ∅(纯叶子) +services / config / templates / src 为叶子资产,仅被消费 +scripts → lib(可选) +``` + +任何目录都**不得反向依赖** core / modules,从结构层面杜绝循环耦合。 + +--- + +## 3. 目录详解 + +### `bin/` —— 入口脚本 +用户直接执行的一层薄壳,仅负责 `cd` 到项目根、`source` 公共库与编排核心、解析最少量参数后委托。 +- `install.sh`:主安装入口,驱动 `core/workflow.sh::main()`。 +- `uninstall.sh` / `upgrade.sh` / `vhost.sh` / `addons.sh` / `backup.sh` / `backup_setup.sh` / `pureftpd_vhost.sh` / `reset_db_root_password.sh`:各自独立职责的管理脚本。 + +### `core/` —— 核心流程编排(13 文件) +项目专属业务逻辑,决定“**先做什么、后做什么**”,但**不持有具体软件的编译/安装代码**。 +- `workflow.sh`:**唯一决定安装顺序**的地方(`main()`)。 +- `environment.sh`:`init_environment` / `init_variables` / `prepare_install` / `check_environment`。 +- `init.sh`:`init_os` / `install_prereqs`(含 `os/` 两个 OS 初始化子脚本)。 +- `argument.sh`:`version` / `Show_Help` / `parse_arguments` / `handle_ssh_port`。 +- `menu.sh`:`show_menu`。 +- `validator.sh`:`is_valid` / `validate_options`(幂等校验安全网)。 +- `installer.sh`:`install_modules` / `configure_modules` / `PHP_addons`。 +- `service.sh`:`start_services` / `start_service`(统一 systemctl | service 双路)。 +- `summary.sh`:`print_summary`。 +- `demo.sh`:演示站点生成。 +- `os/init_Debian.sh` `os/init_Ubuntu.sh`:Debian / Ubuntu 的 OS 初始化(仅支持这两类系统)。 + +### `lib/` —— 公共函数库(15 文件) +纯工具,无任何业务决策、source 时零副作用,可被任意模块安全复用。 +- `loader.sh`:`load_common` / `load_configs` / `source_module` / `run_install`(统一去重的 `. module; Func | tee -a install.log`)。 +- `log.sh`:`log_info` / `log_warn` / `log_error` / `log_success` / `error_exit` / `cleanup` / `rollback` / `trap_handler`。 +- `color.sh` `check_os.sh` `check_dir.sh` `download.sh` `check_download.sh` `get_char.sh` `memory.sh` `openssl.sh` `check_sw.sh`:颜色、系统检测、目录/下载校验、随机密码等工具。 +- `py/`:`get_ipaddr.py` `get_public_ipaddr.py` `get_ipaddr_state.py` `check_port.py`(Python 辅助)。 + +### `modules/` —— 软件安装模块(58 文件,按类别分区) +每个软件一个文件,统一对外暴露 `Install_X`(部分含 `Configure_X` / `Start_X`)。 +新增软件 = 在对应子目录丢一个 `Install_X` 文件 + 在 `installer.sh` / `menu.sh` 注册,**无需改动核心**。 + +| 子目录 | 内容 | +|---|---| +| `web/` | jemalloc, nginx | +| `db/` | mysql-5.7/8.0, mariadb-10.11/11.8/12.3, postgresql-15.14/16.10/17.6, mongodb | +| `php/` | php-7.4/8.0/8.1, mphp(多版本共存) | +| `php-addons/` | apcu, xcache, eaccelerator, ioncube, sourceguardian, ZendGuardLoader, zendopcache, composer, pecl_calendar / fileinfo / imap / ldap / mongodb / pgsql / phalcon / swoole / xdebug / yaf / yar | +| `cache/` | redis | +| `lang/` | nodejs, python | +| `app/` | phpmyadmin | +| `ftp/` | pureftpd | +| `security/` | fail2ban, ngx_lua_waf | +| `image/` | GraphicsMagick, ImageMagick | +| `upgrade/` | upgrade_db / oneinstack / php / phpmyadmin / redis / web | + +### `services/` —— 服务单元(6 文件) +原 `init.d/` 内容,迁移为现代 systemd 单元。 +- `nginx.service` `php-fpm.service` `mongod.service` + `postgresql.service` `pureftpd.service` `redis-server.service`。 + +### `config/` —— 项目配置(2 文件) +- `options.conf`:安装选项(含可存储的数据库密码等)。 +- `versions.txt`:各组件版本清单。 + +### `templates/` —— 配置模板(19 文件) +服务器 / vhost 配置模板(原 `config/` 的 vhost 模板),安装期由 modules 渲染。 +- 通用:`nginx.conf` `pure-ftpd.conf` `index.html` `index_cn.html`。 +- 应用模板:`cloudflare` `codeigniter` `discuz` `drupal` `ecshop` `joomla` `laravel` `magento2` `nextcloud` `opencart` `thinkphp` `typecho` `whmcs` `wordpress` `zblog`(`.conf`)。 + +### `src/` —— 补丁 / 密钥 / 预置包(149 文件) +`libiconv-glibc-2.16.patch` `php5.3patch` +若干编译依赖(注:`nginx-rtmp-module`、`ngx-fancyindex` 已从 Nginx 编译中移除,因其下载源失效且无可用镜像); +其余为离线安装预置的源码 / 二进制 tarball(清单见根目录 `OFFLINE_MANIFEST.txt`)。 +> 注:目录名**保留 `src/` 未改名 `patches/`**。原因:编译脚本中 `src/` 大量指代下载解压后的**源码内部路径**(如 `src/core/nginx.h`、`src/argon2-`),盲目改名会破坏编译逻辑;保留原名零引用风险。 + +### `scripts/` —— 独立运维脚本(7 文件) +`db_bk.sh` `website_bk.sh` `thread.sh` `mabs.sh` `ckssh.py` `mssh.exp` `mscp.exp`。 + +### `runtime/` `logs/` `backup/` —— 生成物目录 +- `runtime/install.log`:安装日志(由 `lib/log.sh::_log_path` 统一写入)。 +- `logs/`、`backup/`:预留给运维日志与备份归档。 + +### `docs/` `tests/` +- `docs/README.md`:上游原使用文档(未改动)。 +- `tests/`:回归 / 冒烟测试骨架(本次仅建目录,待补充)。 + +--- + +## 4. 入口与执行流程 + +`bin/install.sh`(约 40 行,纯入口): + +```bash +#!/bin/bash +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +cd "$(dirname "$(readlink -f "$0")")/.." || exit 1 # cd 到项目根 +. ./lib/loader.sh +. ./lib/log.sh +. ./core/environment.sh +# ... source 其余 core 模块 ... +trap 'trap_handler' EXIT INT TERM +main "$@" +``` + +`main()`(`core/workflow.sh`)按固定顺序编排: + +``` +init_environment → load_configs → init_variables → parse_arguments → +check_environment → show_menu → validate_options → prepare_install → +init_os → install_prereqs → install_modules → configure_modules → +start_services → print_summary +``` + +--- + +## 5. 如何新增一个软件模块(扩展性示范) + +1. 在 `modules/<类别>/` 下新建 `.sh`,实现 `Install_`(及可选的 `Configure_*` / `Start_*`)。 +2. 在 `core/installer.sh` 的安装分支里加一行 `run_install "modules/<类别>/.sh" "Install_"`。 +3. 若需在交互菜单出现,在 `core/menu.sh` 增加对应选项。 +4. 如需 systemd 单元,放入 `services/`。 +5. 如需默认配置文件,放入 `templates/` 并在模块中渲染(经 `lib/` 工具)。 + +**核心编排(`workflow.sh` / `installer.sh` / `menu.sh`)之外无需改动任何公共代码。** + +--- + +## 6. 兼容性说明 + +- ✅ 安装逻辑、安装顺序、CLI 参数、配置格式、菜单、日志**内容**全部不变。 +- ⚠️ 变更**仅限路径/引用**:`./include/X.sh` → 新目录路径;属机械替换,算法/分支零改动。 +- ⚠️ `install.log` 落点改为 `runtime/install.log`(仅路径,内容不变)。 +- ⚠️ `src/` 目录名保留(见第 3 节说明),其余资源目录已按规划重命名。 +- ⚠️ **软件裁剪(Software Trim)**:在重构基础上进一步移除了 Tengine / OpenResty / Apache(仅保留 Nginx)、Percona 全系(仅保留 MySQL / MariaDB / PostgreSQL / MongoDB)、Memcached(仅保留 Redis)、OpenJDK 8/11(仅保留 Node.js / Python)、Tomcat 7–10(仅保留 phpMyAdmin)。菜单 DB 选项已重排:**9 = PostgreSQL、10 = MongoDB**(原 13/14 已上移)。相关安装 / 升级 / 下载 / 检测脚本与离线包清单均已同步裁剪,详见 `OFFLINE.md` 第 4 节。 + +--- + +## 7. 校验状态 + +- ✅ 全部 `.sh` 通过 `bash -n` 语法检查。 +- ✅ source 冒烟测试:框架函数全部定义、路径全部解析成功。 +- ✅ 所有 `run_install` / `. modules/` / `. lib/` / `. core/` 引用均指向真实存在的文件。 +- ✅ 全局无残留 `include/` 误引用;`$HOME/.oneinstack` 标记未受影响。 +- ⏳ 待 Linux 主机动态回归:干净容器(Debian + Ubuntu 各一)交互 & CLI 两种模式, + 对照原 `oneinstack/install.sh.bak` 比较 `install.log` / 汇总 / 产物目录;并补 `shellcheck -S error`。 diff --git a/bin/addons.sh b/bin/addons.sh new file mode 100644 index 0000000..a3dd390 --- /dev/null +++ b/bin/addons.sh @@ -0,0 +1,212 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# Install/Uninstall Extensions # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +# shellcheck disable=SC2046 +[ $(id -u) != '0' ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +# shellcheck disable=SC2164 +cd "${oneinstack_dir}" || exit 1 + +. ./config/versions.txt +. ./config/options.conf +. ./lib/color.sh +. ./lib/check_os.sh +. ./lib/download.sh +. ./lib/get_char.sh + +. ./modules/php-addons/composer.sh + +. ./modules/lang/python.sh + +. ./modules/security/fail2ban.sh + +. ./modules/security/ngx_lua_waf.sh + +# shellcheck disable=SC2154 +Show_Help() { + echo + echo "Usage: $0 command ... + --help, -h Show this help message + --install, -i Install + --uninstall, -u Uninstall + --composer Composer + --fail2ban Fail2ban + --ngx_lua_waf Ngx_lua_waf + --python Python (PATH: ${python_install_dir}) + " +} + +ARG_NUM=$# +TEMP=`getopt -o hiu --long help,install,uninstall,composer,fail2ban,ngx_lua_waf,python -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + -i|--install) + install_flag=y; shift 1 + ;; + -u|--uninstall) + uninstall_flag=y; shift 1 + ;; + --composer) + composer_flag=y; shift 1 + ;; + --fail2ban) + fail2ban_flag=y; shift 1 + ;; + --ngx_lua_waf) + ngx_lua_waf_flag=y; shift 1 + ;; + --python) + python_flag=y; shift 1 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +ACTION_FUN() { + while :; do + echo + echo "Please select an action:" + echo -e "\t${CMSG}1${CEND}. install" + echo -e "\t${CMSG}2${CEND}. uninstall" + read -e -p "Please input a number:(Default 1 press Enter) " ACTION + ACTION=${ACTION:-1} + if [[ ! "${ACTION}" =~ ^[1,2]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~2${CEND}" + else + [ "${ACTION}" == '1' ] && install_flag=y + [ "${ACTION}" == '2' ] && uninstall_flag=y + break + fi + done +} + +Menu() { + while :;do + printf " +What Are You Doing? +\t${CMSG}1${CEND}. Install/Uninstall PHP Composer +\t${CMSG}2${CEND}. Install/Uninstall fail2ban +\t${CMSG}3${CEND}. Install/Uninstall ngx_lua_waf +\t${CMSG}4${CEND}. Install/Uninstall Python3.6 +\t${CMSG}q${CEND}. Exit +" + read -e -p "Please input the correct option: " Number + if [[ ! "${Number}" =~ ^[1-5,q]$ ]]; then + echo "${CFAILURE}input error! Please only input 1~4 and q${CEND}" + else + case "${Number}" in + 1) + ACTION_FUN + if [ "${install_flag}" = 'y' ]; then + Install_composer + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_composer + fi + ;; + 2) + ACTION_FUN + if [ "${install_flag}" = 'y' ]; then + Install_Python + Install_fail2ban + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_fail2ban + fi + ;; + 3) + ACTION_FUN + if [ "${install_flag}" = 'y' ]; then + # shellcheck disable=SC2154 + [ -e "${nginx_install_dir}/sbin/nginx" ] && Nginx_lua_waf + enable_lua_waf + elif [ "${uninstall_flag}" = 'y' ]; then + disable_lua_waf + fi + ;; + 4) + ACTION_FUN + if [ "${install_flag}" = 'y' ]; then + Install_Python + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_Python + fi + ;; + 5) + ACTION_FUN + if [ "${install_flag}" = 'y' ]; then + Install_Python + Install_Panel + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_Panel + fi + ;; + q) + exit + ;; + esac + fi + done +} + +if [ ${ARG_NUM} == 0 ]; then + Menu +else + if [ "${composer_flag}" == 'y' ]; then + if [ "${install_flag}" = 'y' ]; then + Install_composer + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_composer + fi + fi + if [ "${fail2ban_flag}" == 'y' ]; then + if [ "${install_flag}" = 'y' ]; then + Install_Python + Install_fail2ban + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_fail2ban + fi + fi + if [ "${ngx_lua_waf_flag}" == 'y' ]; then + if [ "${install_flag}" = 'y' ]; then + [ -e "${nginx_install_dir}/sbin/nginx" ] && Nginx_lua_waf + enable_lua_waf + elif [ "${uninstall_flag}" = 'y' ]; then + disable_lua_waf + fi + fi + if [ "${python_flag}" == 'y' ]; then + if [ "${install_flag}" = 'y' ]; then + Install_Python + elif [ "${uninstall_flag}" = 'y' ]; then + Uninstall_Python + fi + fi +fi diff --git a/bin/backup.sh b/bin/backup.sh new file mode 100644 index 0000000..e6b199d --- /dev/null +++ b/bin/backup.sh @@ -0,0 +1,295 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir=$(dirname "`readlink -f $0`") +pushd ${oneinstack_dir}/tools > /dev/null +. ../config/options.conf +[ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + +DB_Local_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + done +} + +DB_Remote_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + echo "file:::${backup_dir}/${DB_FILE} ${backup_dir} push" >> config_backup.txt + echo "com:::[ -e "${backup_dir}/${DB_FILE}" ] && rm -rf ${backup_dir}/DB_${D}_$(date +%Y%m%d --date="${expired_days} days ago")_*.tgz" >> config_backup.txt + done +} + +DB_OSS_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + /usr/local/bin/ossutil cp -f ${backup_dir}/${DB_FILE} oss://${oss_bucket}/`date +%F`/${DB_FILE} + if [ $? -eq 0 ]; then + /usr/local/bin/ossutil rm -rf oss://${oss_bucket}/`date +%F --date="${expired_days} days ago"`/ + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + fi + done +} + +DB_COS_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + ${python_install_dir}/bin/coscmd upload ${backup_dir}/${DB_FILE} /`date +%F`/${DB_FILE} + if [ $? -eq 0 ]; then + ${python_install_dir}/bin/coscmd delete -r -f `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + fi + done +} + +DB_UPYUN_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + /usr/local/bin/upx put ${backup_dir}/${DB_FILE} /`date +%F`/${DB_FILE} + if [ $? -eq 0 ]; then + /usr/local/bin/upx rm -a `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + fi + done +} + +DB_QINIU_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + /usr/local/bin/qshell rput ${qiniu_bucket} /`date +%F`/${DB_FILE} ${backup_dir}/${DB_FILE} + if [ $? -eq 0 ]; then + /usr/local/bin/qshell listbucket ${qiniu_bucket} /`date +%F --date="${expired_days} days ago"` /tmp/qiniu.txt > /dev/null 2>&1 + /usr/local/bin/qshell batchdelete -force ${qiniu_bucket} /tmp/qiniu.txt > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + rm -f /tmp/qiniu.txt + fi + done +} + +DB_S3_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + ${python_install_dir}/bin/s3cmd put ${backup_dir}/${DB_FILE} s3://${s3_bucket}/`date +%F`/${DB_FILE} + if [ $? -eq 0 ]; then + ${python_install_dir}/bin/s3cmd rm -r s3://${s3_bucket}/`date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + fi + done +} + +DB_DROPBOX_BK() { + for D in `echo ${db_name} | tr ',' ' '` + do + ./db_bk.sh ${D} + DB_GREP="DB_${D}_`date +%Y%m%d`" + DB_FILE=`ls -lrt ${backup_dir} | grep ${DB_GREP} | tail -1 | awk '{print $NF}'` + /usr/local/bin/dbxcli put ${backup_dir}/${DB_FILE} `date +%F`/${DB_FILE} + if [ $? -eq 0 ]; then + /usr/local/bin/dbxcli rm -f `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${backup_dir}/${DB_FILE} + fi + done +} + +WEB_LOCAL_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + ./website_bk.sh $W + done +} + +WEB_Remote_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + if [ `du -sm "${wwwroot_dir}/${WebSite}" | awk '{print $1}'` -lt 2048 ]; then + ./website_bk.sh $W + Web_GREP="Web_${W}_`date +%Y%m%d`" + Web_FILE=`ls -lrt ${backup_dir} | grep ${Web_GREP} | tail -1 | awk '{print $NF}'` + echo "file:::${backup_dir}/${Web_FILE} ${backup_dir} push" >> config_backup.txt + echo "com:::[ -e "${backup_dir}/${Web_FILE}" ] && rm -rf ${backup_dir}/Web_${W}_$(date +%Y%m%d --date="${expired_days} days ago")_*.tgz" >> config_backup.txt + else + echo "file:::${wwwroot_dir}/$W ${backup_dir} push" >> config_backup.txt + fi + done +} + +WEB_OSS_BK() { + for W in `echo $website_name | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + /usr/local/bin/ossutil cp -f ${PUSH_FILE} oss://${oss_bucket}/`date +%F`/${PUSH_FILE##*/} + if [ $? -eq 0 ]; then + /usr/local/bin/ossutil rm -rf oss://${oss_bucket}/`date +%F --date="${expired_days} days ago"`/ + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + fi + done +} + +WEB_COS_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + ${python_install_dir}/bin/coscmd upload ${PUSH_FILE} /`date +%F`/${PUSH_FILE##*/} + if [ $? -eq 0 ]; then + ${python_install_dir}/bin/coscmd delete -r -f `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + fi + done +} + +WEB_UPYUN_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + [ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + /usr/local/bin/upx put ${PUSH_FILE} /`date +%F`/${PUSH_FILE##*/} + if [ $? -eq 0 ]; then + /usr/local/bin/upx rm -a `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + fi + done +} + +WEB_QINIU_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + [ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + /usr/local/bin/qshell rput ${qiniu_bucket} /`date +%F`/${PUSH_FILE##*/} ${PUSH_FILE} + if [ $? -eq 0 ]; then + /usr/local/bin/qshell listbucket ${qiniu_bucket} /`date +%F --date="${expired_days} days ago"` /tmp/qiniu.txt > /dev/null 2>&1 + /usr/local/bin/qshell batchdelete -force ${qiniu_bucket} /tmp/qiniu.txt > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + rm -f /tmp/qiniu.txt + fi + done +} + +WEB_S3_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + [ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + ${python_install_dir}/bin/s3cmd put ${PUSH_FILE} s3://${s3_bucket}/`date +%F`/${PUSH_FILE##*/} + if [ $? -eq 0 ]; then + ${python_install_dir}/bin/s3cmd rm -r s3://${s3_bucket}/`date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + fi + done +} + +WEB_DROPBOX_BK() { + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist"; break; } + [ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + PUSH_FILE="${backup_dir}/Web_${W}_$(date +%Y%m%d_%H).tgz" + if [ ! -e "${PUSH_FILE}" ]; then + pushd ${wwwroot_dir} > /dev/null + tar czf ${PUSH_FILE} ./$W + popd > /dev/null + fi + /usr/local/bin/dbxcli put ${PUSH_FILE} `date +%F`/${PUSH_FILE##*/} + if [ $? -eq 0 ]; then + /usr/local/bin/dbxcli rm -f `date +%F --date="${expired_days} days ago"` > /dev/null 2>&1 + [ -z "`echo ${backup_destination} | grep -ow 'local'`" ] && rm -f ${PUSH_FILE} + fi + done +} + +for DEST in `echo ${backup_destination} | tr ',' ' '` +do + if [ "${DEST}" == 'local' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_Local_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_LOCAL_BK + fi + if [ "${DEST}" == 'remote' ]; then + echo "com:::[ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir}" > config_backup.txt + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_Remote_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_Remote_BK + ./mabs.sh -c config_backup.txt -T -1 | tee -a mabs.log + fi + if [ "${DEST}" == 'oss' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_OSS_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_OSS_BK + fi + if [ "${DEST}" == 'cos' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_COS_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_COS_BK + fi + if [ "${DEST}" == 'upyun' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_UPYUN_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_UPYUN_BK + fi + if [ "${DEST}" == 'qiniu' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_QINIU_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_QINIU_BK + fi + if [ "${DEST}" == 's3' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_S3_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_S3_BK + fi + if [ "${DEST}" == 'dropbox' ]; then + [ -n "`echo ${backup_content} | grep -ow db`" ] && DB_DROPBOX_BK + [ -n "`echo ${backup_content} | grep -ow web`" ] && WEB_DROPBOX_BK + fi +done diff --git a/bin/backup_setup.sh b/bin/backup_setup.sh new file mode 100644 index 0000000..ba0e8e0 --- /dev/null +++ b/bin/backup_setup.sh @@ -0,0 +1,535 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# Setup the backup parameters # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/options.conf +. ./config/versions.txt +. ./lib/color.sh +. ./lib/check_os.sh +. ./lib/check_dir.sh +. ./lib/download.sh +. ./modules/lang/python.sh + +while :; do echo + echo 'Please select your backup destination:' + echo -e "\t${CMSG}1${CEND}. Localhost" + echo -e "\t${CMSG}2${CEND}. Remote host" + echo -e "\t${CMSG}3${CEND}. Aliyun OSS" + echo -e "\t${CMSG}4${CEND}. Qcloud COS" + echo -e "\t${CMSG}5${CEND}. UPYUN" + echo -e "\t${CMSG}6${CEND}. QINIU" + echo -e "\t${CMSG}7${CEND}. Amazon S3" + echo -e "\t${CMSG}8${CEND}. Dropbox" + read -e -p "Please input numbers:(Default 1 press Enter) " desc_bk + desc_bk=${desc_bk:-'1'} + array_desc=(${desc_bk}) + array_all=(1 2 3 4 5 6 7 8) + for v in ${array_desc[@]} + do + [ -z "`echo ${array_all[@]} | grep -w ${v}`" ] && desc_flag=1 + done + if [ "${desc_flag}" == '1' ]; then + unset desc_flag + echo; echo "${CWARNING}input error! Please only input number 1 3 4 and so on${CEND}"; echo + continue + else + sed -i 's@^backup_destination=.*@backup_destination=@' ./config/options.conf + break + fi +done + +[ -n "`echo ${desc_bk} | grep -w 1`" ] && sed -i 's@^backup_destination=.*@backup_destination=local@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 2`" ] && sed -i 's@^backup_destination=.*@&,remote@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 3`" ] && sed -i 's@^backup_destination=.*@&,oss@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 4`" ] && sed -i 's@^backup_destination=.*@&,cos@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 5`" ] && sed -i 's@^backup_destination=.*@&,upyun@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 6`" ] && sed -i 's@^backup_destination=.*@&,qiniu@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 7`" ] && sed -i 's@^backup_destination=.*@&,s3@' ./config/options.conf +[ -n "`echo ${desc_bk} | grep -w 8`" ] && sed -i 's@^backup_destination=.*@&,dropbox@' ./config/options.conf +sed -i 's@^backup_destination=,@backup_destination=@' ./config/options.conf + +while :; do echo + echo 'Please select your backup content:' + echo -e "\t${CMSG}1${CEND}. Only Database" + echo -e "\t${CMSG}2${CEND}. Only Website" + echo -e "\t${CMSG}3${CEND}. Database and Website" + read -e -p "Please input a number:(Default 1 press Enter) " content_bk + content_bk=${content_bk:-1} + if [[ ! ${content_bk} =~ ^[1-3]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~3${CEND}" + else + break + fi +done + +[ "${content_bk}" == '1' ] && sed -i 's@^backup_content=.*@backup_content=db@' ./config/options.conf +[ "${content_bk}" == '2' ] && sed -i 's@^backup_content=.*@backup_content=web@' ./config/options.conf +[ "${content_bk}" == '3' ] && sed -i 's@^backup_content=.*@backup_content=db,web@' ./config/options.conf + +if [ -n "`echo ${desc_bk} | grep -Ew '1|2'`" ]; then + while :; do echo + echo "Please enter the directory for save the backup file: " + read -e -p "(Default directory: ${backup_dir}): " new_backup_dir + new_backup_dir=${new_backup_dir:-${backup_dir}} + if [ -z "`echo ${new_backup_dir}| grep '^/'`" ]; then + echo "${CWARNING}input error! ${CEND}" + else + break + fi + done + sed -i "s@^backup_dir=.*@backup_dir=${new_backup_dir}@" ./config/options.conf +fi + +while :; do echo + echo "Please enter a valid backup number of days: " + read -e -p "(Default days: 5): " expired_days + expired_days=${expired_days:-5} + [ -n "`echo ${expired_days} | sed -n "/^[0-9]\+$/p"`" ] && break || echo "${CWARNING}input error! Please only enter numbers! ${CEND}" +done +sed -i "s@^expired_days=.*@expired_days=${expired_days}@" ./config/options.conf + +if [ "${content_bk}" != '2' ]; then + databases=`${db_install_dir}/bin/mysql -uroot -p$dbrootpwd -e "show databases\G" | grep Database | awk '{print $2}' | grep -Evw "(performance_schema|information_schema|mysql|sys)"` + while :; do echo + echo "Please enter one or more name for database, separate multiple database names with commas: " + read -e -p "(Default database: `echo $databases | tr ' ' ','`) " db_name + db_name=`echo ${db_name} | tr -d ' '` + [ -z "${db_name}" ] && db_name="`echo $databases | tr ' ' ','`" + D_tmp=0 + for D in `echo ${db_name} | tr ',' ' '` + do + [ -z "`echo $databases | grep -w $D`" ] && { echo "${CWARNING}$D was not exist! ${CEND}" ; D_tmp=1; } + done + [ "$D_tmp" != '1' ] && break + done + sed -i "s@^db_name=.*@db_name=${db_name}@" ./config/options.conf +fi + +if [ "${content_bk}" != '1' ]; then + websites=`ls ${wwwroot_dir}` + while :; do echo + echo "Please enter one or more name for website, separate multiple website names with commas: " + read -e -p "(Default website: `echo $websites | tr ' ' ','`) " website_name + website_name=`echo ${website_name} | tr -d ' '` + [ -z "${website_name}" ] && website_name="`echo $websites | tr ' ' ','`" + W_tmp=0 + for W in `echo ${website_name} | tr ',' ' '` + do + [ ! -e "${wwwroot_dir}/$W" ] && { echo "${CWARNING}${wwwroot_dir}/$W not exist! ${CEND}" ; W_tmp=1; } + done + [ "$W_tmp" != '1' ] && break + done + sed -i "s@^website_name=.*@website_name=${website_name}@" ./config/options.conf +fi + +echo +echo "You have to backup the content:" +[ "${content_bk}" != '2' ] && echo "Database: ${CMSG}${db_name}${CEND}" +[ "${content_bk}" != '1' ] && echo "Website: ${CMSG}${website_name}${CEND}" + +if [ -n "`echo ${desc_bk} | grep -w 2`" ]; then + > tools/iplist.txt + while :; do echo + read -e -p "Please enter the remote host address: " remote_address + [ -z "${remote_address}" -o "${remote_address}" == '127.0.0.1' ] && continue + echo + read -e -p "Please enter the remote host port(Default: 22) : " remote_port + remote_port=${remote_port:-22} + echo + read -e -p "Please enter the remote host user(Default: root) : " remote_user + remote_user=${remote_user:-root} + echo + read -e -p "Please enter the remote host password: " remote_password + IPcode=$(echo "ibase=16;$(echo "${remote_address}" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + Portcode=$(echo "ibase=16;$(echo "${remote_port}" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + PWcode=$(echo "ibase=16;$(echo "$remote_password" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + [ -e "~/.ssh/known_hosts" ] && grep ${remote_address} ~/.ssh/known_hosts | sed -i "/${remote_address}/d" ~/.ssh/known_hosts + ./tools/mssh.exp ${IPcode}P ${remote_user} ${PWcode}P ${Portcode}P true 10 + if [ $? -eq 0 ]; then + [ -z "`grep ${remote_address} tools/iplist.txt`" ] && echo "${remote_address} ${remote_port} ${remote_user} $remote_password" >> tools/iplist.txt || echo "${CWARNING}${remote_address} has been added! ${CEND}" + while :; do + read -e -p "Do you want to add more host ? [y/n]: " morehost_flag + if [[ ! ${morehost_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + [ "${morehost_flag}" == 'n' ] && break + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 3`" ]; then + if [ ! -e "/usr/local/bin/ossutil" ]; then + if [ "${armplatform}" == 'y' ]; then + wget -qc https://gosspublic.alicdn.com/ossutil/1.7.10/ossutilarm64 -O /usr/local/bin/ossutil + else + wget -qc https://gosspublic.alicdn.com/ossutil/1.7.10/ossutil64 -O /usr/local/bin/ossutil + fi + chmod +x /usr/local/bin/ossutil + fi + while :; do echo + echo 'Please select your backup aliyun datacenter:' + echo -e "\t ${CMSG}1${CEND}. cn-hangzhou-华东1 (杭州) ${CMSG}2${CEND}. cn-shanghai-华东2 (上海)" + echo -e "\t ${CMSG}3${CEND}. cn-qingdao-华北1 (青岛) ${CMSG}4${CEND}. cn-beijing-华北2 (北京)" + echo -e "\t ${CMSG}5${CEND}. cn-zhangjiakou-华北3 (张家口) ${CMSG}6${CEND}. cn-huhehaote-华北5(呼和浩特)" + echo -e "\t ${CMSG}7${CEND}. cn-wulanchabu-华北6(乌兰察布) ${CMSG}8${CEND}. cn-shenzhen-华南1(深圳)" + echo -e "\t ${CMSG}9${CEND}. cn-heyuan-华南2(河源) ${CMSG}10${CEND}. cn-guangzhou-华南3(广州)" + echo -e "\t${CMSG}11${CEND}. cn-chengdu-西南1(成都) ${CMSG}12${CEND}. cn-hongkong-香港" + echo -e "\t${CMSG}13${CEND}. us-west-1-美国(硅谷) ${CMSG}14${CEND}. us-east-1-美国(弗吉尼亚)" + echo -e "\t${CMSG}15${CEND}. ap-southeast-1-新加坡 ${CMSG}16${CEND}. ap-southeast-2-澳大利亚(悉尼)" + echo -e "\t${CMSG}17${CEND}. ap-southeast-3-马来西亚(吉隆坡)${CMSG}18${CEND}. ap-southeast-5-印度尼西亚(雅加达)" + echo -e "\t${CMSG}19${CEND}. ap-northeast-1-日本(东京) ${CMSG}20${CEND}. ap-south-1-印度(孟买)" + echo -e "\t${CMSG}21${CEND}. eu-central-1-德国(法兰克福) ${CMSG}22${CEND}. eu-west-1-英国(伦敦)" + echo -e "\t${CMSG}23${CEND}. me-east-1-中东东部 (迪拜) ${CMSG}24${CEND}. ap-southeast-6-菲律宾(马尼拉)" + read -e -p "Please input a number:(Default 1 press Enter) " Location + Location=${Location:-1} + if [[ "${Location}" =~ ^[1-9]$|^1[0-9]$|^24$ ]]; then + break + else + echo "${CWARNING}input error! Please only input number 1~24${CEND}" + fi + done + [ "${Location}" == '1' ] && Host=oss-cn-hangzhou-internal.aliyuncs.com + [ "${Location}" == '2' ] && Host=oss-cn-shanghai-internal.aliyuncs.com + [ "${Location}" == '3' ] && Host=oss-cn-qingdao-internal.aliyuncs.com + [ "${Location}" == '4' ] && Host=oss-cn-beijing-internal.aliyuncs.com + [ "${Location}" == '5' ] && Host=oss-cn-zhangjiakou-internal.aliyuncs.com + [ "${Location}" == '6' ] && Host=oss-cn-huhehaote-internal.aliyuncs.com + [ "${Location}" == '7' ] && Host=oss-cn-wulanchabu-internal.aliyuncs.com + [ "${Location}" == '8' ] && Host=oss-cn-shenzhen-internal.aliyuncs.com + [ "${Location}" == '9' ] && Host=oss-cn-heyuan-internal.aliyuncs.com + [ "${Location}" == '10' ] && Host=oss-cn-guangzhou-internal.aliyuncs.com + [ "${Location}" == '11' ] && Host=oss-cn-chengdu-internal.aliyuncs.com + [ "${Location}" == '12' ] && Host=oss-cn-hongkong-internal.aliyuncs.com + [ "${Location}" == '13' ] && Host=oss-us-west-1-internal.aliyuncs.com + [ "${Location}" == '14' ] && Host=oss-us-east-1-internal.aliyuncs.com + [ "${Location}" == '15' ] && Host=oss-ap-southeast-1-internal.aliyuncs.com + [ "${Location}" == '16' ] && Host=oss-ap-southeast-2-internal.aliyuncs.com + [ "${Location}" == '17' ] && Host=oss-ap-southeast-3-internal.aliyuncs.com + [ "${Location}" == '18' ] && Host=oss-ap-southeast-5-internal.aliyuncs.com + [ "${Location}" == '19' ] && Host=oss-ap-northeast-1-internal.aliyuncs.com + [ "${Location}" == '20' ] && Host=oss-ap-south-1-internal.aliyuncs.com + [ "${Location}" == '21' ] && Host=oss-eu-central-1-internal.aliyuncs.com + [ "${Location}" == '22' ] && Host=oss-eu-west-1-internal.aliyuncs.com + [ "${Location}" == '23' ] && Host=oss-me-east-1-internal.aliyuncs.com + [ "${Location}" == '24' ] && Host=oss-ap-southeast-6-internal.aliyuncs.com + [ "$(./lib/py/check_port.py ${Host} 80)" == "False" ] && Host=`echo ${Host} | sed 's@-internal@@g'` + [ -e "/root/.ossutilconfig" ] && rm -f /root/.ossutilconfig + while :; do echo + read -e -p "Please enter the aliyun oss Access Key ID: " KeyID + [ -z "${KeyID}" ] && continue + echo + read -e -p "Please enter the aliyun oss Access Key Secret: " KeySecret + [ -z "${KeySecret}" ] && continue + /usr/local/bin/ossutil ls -e ${Host} -i ${KeyID} -k ${KeySecret} > /dev/null 2>&1 + if [ $? -eq 0 ]; then + /usr/local/bin/ossutil config -e ${Host} -i ${KeyID} -k ${KeySecret} > /dev/null 2>&1 + while :; do echo + read -e -p "Please enter the aliyun oss bucket: " OSS_BUCKET + /usr/local/bin/ossutil mb oss://${OSS_BUCKET} > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "${CMSG}Bucket oss://${OSS_BUCKET}/ created${CEND}" + sed -i "s@^oss_bucket=.*@oss_bucket=${OSS_BUCKET}@" ./config/options.conf + break + else + echo "${CWARNING}[${OSS_BUCKET}] already exists, You need to use the OSS Console to create a bucket for storing.${CEND}" + fi + done + break + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 4`" ]; then + Install_Python + [ ! -e "${python_install_dir}/bin/coscmd" ] && ${python_install_dir}/bin/pip install coscmd > /dev/null 2>&1 + while :; do echo + echo 'Please select your backup qcloud datacenter:' + echo -e "\t ${CMSG} 1${CEND}. ap-beijing-1-北京一区(华北) ${CMSG}2${CEND}. ap-beijing-北京" + echo -e "\t ${CMSG} 3${CEND}. ap-nanjing-南京 ${CMSG}4${CEND}. ap-shanghai-上海" + echo -e "\t ${CMSG} 5${CEND}. ap-guangzhou-广州 ${CMSG}6${CEND}. ap-chengdu-成都" + echo -e "\t ${CMSG} 7${CEND}. ap-chongqing-重庆 ${CMSG}8${CEND}. ap-shenzhen-fsi-深圳金融" + echo -e "\t ${CMSG} 9${CEND}. ap-shanghai-fsi-上海金融 ${CMSG}10${CEND}. ap-beijing-fsi-北京金融" + echo -e "\t ${CMSG}11${CEND}. ap-hongkong-香港 ${CMSG}11${CEND}. ap-singapore-新加坡" + echo -e "\t ${CMSG}13${CEND}. ap-mumbai-孟买 ${CMSG}14${CEND}. ap-jakarta-雅加达" + echo -e "\t ${CMSG}15${CEND}. ap-seoul-首尔 ${CMSG}16${CEND}. ap-bangkok-曼谷" + echo -e "\t ${CMSG}17${CEND}. ap-tokyo-东京 ${CMSG}18${CEND}. na-siliconvalley-硅谷(美西)" + echo -e "\t ${CMSG}19${CEND}. na-ashburn-弗吉尼亚(美东) ${CMSG}20${CEND}. na-toronto-多伦多" + echo -e "\t ${CMSG}21${CEND}. sa-saopaulo-圣保罗 ${CMSG}22${CEND}. eu-frankfurt-法兰克福" + echo -e "\t ${CMSG}23${CEND}. eu-moscow-莫斯科" + read -e -p "Please input a number:(Default 1 press Enter) " Location + Location=${Location:-1} + if [[ "${Location}" =~ ^[1-9]$|^1[0-9]$|^2[0-3]$ ]]; then + break + else + echo "${CWARNING}input error! Please only input number 1~23${CEND}" + fi + done + [ "${Location}" == '1' ] && REGION='ap-beijing-1' + [ "${Location}" == '2' ] && REGION='ap-beijing' + [ "${Location}" == '3' ] && REGION='ap-nanjing' + [ "${Location}" == '4' ] && REGION='ap-shanghai' + [ "${Location}" == '5' ] && REGION='ap-guangzhou' + [ "${Location}" == '6' ] && REGION='ap-chengdu' + [ "${Location}" == '7' ] && REGION='ap-chongqing' + [ "${Location}" == '8' ] && REGION='ap-shenzhen-fsi' + [ "${Location}" == '9' ] && REGION='ap-shanghai-fsi' + [ "${Location}" == '10' ] && REGION='ap-beijing-fsi' + [ "${Location}" == '11' ] && REGION='ap-hongkong' + [ "${Location}" == '12' ] && REGION='ap-singapore' + [ "${Location}" == '13' ] && REGION='ap-mumbai' + [ "${Location}" == '14' ] && REGION='ap-jakarta' + [ "${Location}" == '15' ] && REGION='ap-seoul' + [ "${Location}" == '16' ] && REGION='ap-bangkok' + [ "${Location}" == '17' ] && REGION='ap-tokyo' + [ "${Location}" == '18' ] && REGION='na-siliconvalley' + [ "${Location}" == '19' ] && REGION='na-ashburn' + [ "${Location}" == '20' ] && REGION='na-toronto' + [ "${Location}" == '21' ] && REGION='sa-saopaulo' + [ "${Location}" == '22' ] && REGION='eu-frankfurt' + [ "${Location}" == '23' ] && REGION='eu-moscow' + while :; do echo + read -e -p "Please enter the Qcloud COS APPID: " APPID + [[ ! "${APPID}" =~ ^[0-9]+$ ]] && { echo "${CWARNING}input error, must be a number${CEND}"; continue; } + echo + read -e -p "Please enter the Qcloud COS SECRET_ID: " SECRET_ID + [ -z "${SECRET_ID}" ] && continue + echo + read -e -p "Please enter the Qcloud COS SECRET_KEY: " SECRET_KEY + [ -z "${SECRET_KEY}" ] && continue + echo + read -e -p "Please enter the Qcloud COS BUCKET: " COS_BUCKET + if [[ ${COS_BUCKET} =~ "-${APPID}"$ ]]; then + COS_BUCKET=${COS_BUCKET} + else + [ -z "${COS_BUCKET}" ] && continue + echo + COS_BUCKET=${COS_BUCKET}-${APPID} + fi + ${python_install_dir}/bin/coscmd config -u ${APPID} -a ${SECRET_ID} -s ${SECRET_KEY} -r ${REGION} -b ${COS_BUCKET} > /dev/null 2>&1 + ${python_install_dir}/bin/coscmd list > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "${CMSG}APPID/SECRET_ID/SECRET_KEY/REGION/BUCKET OK${CEND}" + echo + break + else + ${python_install_dir}/bin/coscmd -b ${COS_BUCKET} createbucket > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "${CMSG}Bucket ${COS_BUCKET} created${CEND}" + echo + break + else + echo "${CWARNING}input error! APPID/SECRET_ID/SECRET_KEY/REGION/BUCKET invalid${CEND}" + continue + fi + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 5`" ]; then + if [ ! -e "/usr/local/bin/upx" ]; then + if [ "${armplatform}" == 'y' ]; then + wget -qc http://collection.b0.upaiyun.com/softwares/upx/upx_0.3.6_linux_arm64.tar.gz -O /tmp/upx_0.3.6_linux_arm64.tar.gz + tar xzf /tmp/upx_0.3.6_linux_arm64.tar.gz -C /tmp/ + else + wget -qc http://collection.b0.upaiyun.com/softwares/upx/upx_0.3.6_linux_x86_64.tar.gz -O /tmp/upx_0.3.6_linux_x86_64.tar.gz + tar xzf /tmp/upx_0.3.6_linux_x86_64.tar.gz -C /tmp/ + fi + /bin/mv /tmp/upx /usr/local/bin/upx + chmod +x /usr/local/bin/upx + rm -f /tmp/upx_* /tmp/LICENSE /tmp/README.md + fi + while :; do echo + read -e -p "Please enter the upyun ServiceName: " ServiceName + [ -z "${ServiceName}" ] && continue + echo + read -e -p "Please enter the upyun Operator: " Operator + [ -z "${Operator}" ] && continue + echo + read -e -p "Please enter the upyun Password: " Password + [ -z "${Password}" ] && continue + echo + /usr/local/bin/upx login ${ServiceName} ${Operator} ${Password} > /dev/null 2>&1 + if [ $? = 0 ]; then + echo "${CMSG}ServiceName/Operator/Password OK${CEND}" + echo + break + else + echo "${CWARNING}input error! ServiceName/Operator/Password invalid${CEND}" + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 6`" ]; then + if [ ! -e "/usr/local/bin/qshell" ]; then + if [ "${armplatform}" == 'y' ]; then + wget -qc https://devtools.qiniu.com/qshell-v2.6.2-linux-arm64.tar.gz -O /tmp/qshell-v2.6.2-linux-arm64.tar.gz + tar xzf /tmp/qshell-v2.6.2-linux-arm64.tar.gz -C /usr/local/bin/ + else + wget -qc https://devtools.qiniu.com/qshell-v2.6.2-linux-amd64.tar.gz -O /tmp/qshell-v2.6.2-linux-amd64.tar.gz + tar xzf /tmp/qshell-v2.6.2-linux-amd64.tar.gz -C /usr/local/bin/ + fi + chmod +x /usr/local/bin/qshell + rm -f /tmp/qshell* + fi + while :; do echo + echo 'Please select your backup qiniu datacenter:' + echo -e "\t ${CMSG} 1${CEND}. 华东 ${CMSG}2${CEND}. 华北" + echo -e "\t ${CMSG} 3${CEND}. 华南 ${CMSG}4${CEND}. 北美" + echo -e "\t ${CMSG} 5${CEND}. 东南亚 ${CMSG}6${CEND}. 华东-浙江2" + read -e -p "Please input a number:(Default 1 press Enter) " Location + Location=${Location:-1} + if [[ "${Location}" =~ ^[1-6]$ ]]; then + break + else + echo "${CWARNING}input error! Please only input number 1~6${CEND}" + fi + done + [ "${Location}" == '1' ] && zone='z0' + [ "${Location}" == '2' ] && zone='z1' + [ "${Location}" == '3' ] && zone='z2' + [ "${Location}" == '4' ] && zone='na0' + [ "${Location}" == '5' ] && zone='as0' + [ "${Location}" == '6' ] && zone='cn-east-2' + while :; do echo + read -e -p "Please enter the qiniu AccessKey: " AccessKey + [ -z "${AccessKey}" ] && continue + echo + read -e -p "Please enter the qiniu SecretKey: " SecretKey + [ -z "${SecretKey}" ] && continue + echo + read -e -p "Please enter the qiniu bucket: " QINIU_BUCKET + [ -z "${QINIU_BUCKET}" ] && continue + echo + /usr/local/bin/qshell account ${AccessKey} ${SecretKey} backup + if /usr/local/bin/qshell buckets | grep -w ${QINIU_BUCKET} > /dev/null 2>&1; then + sed -i "s@^qiniu_bucket=.*@qiniu_bucket=${QINIU_BUCKET}@" ./config/options.conf + echo "${CMSG}AccessKey/SecretKey/Bucket OK${CEND}" + echo + break + else + echo "${CWARNING}input error! AccessKey/SecretKey/Bucket invalid${CEND}" + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 7`" ]; then + Install_Python + [ ! -e "${python_install_dir}/bin/s3cmd" ] && ${python_install_dir}/bin/pip install s3cmd > /dev/null 2>&1 + while :; do echo + echo 'Please select your backup amazon datacenter:' + echo -e "\t ${CMSG} 1${CEND}. us-east-2 ${CMSG} 2${CEND}. us-east-1" + echo -e "\t ${CMSG} 3${CEND}. us-west-1 ${CMSG} 4${CEND}. us-west-2" + echo -e "\t ${CMSG} 5${CEND}. ap-south-1 ${CMSG} 6${CEND}. ap-northeast-3" + echo -e "\t ${CMSG} 7${CEND}. ap-northeast-2 ${CMSG} 8${CEND}. ap-southeast-1" + echo -e "\t ${CMSG} 9${CEND}. ap-southeast-2 ${CMSG}10${CEND}. ap-northeast-1" + echo -e "\t ${CMSG}11${CEND}. ca-central-1 ${CMSG}12${CEND}. cn-north-1" + echo -e "\t ${CMSG}13${CEND}. cn-northwest-1 ${CMSG}14${CEND}. eu-central-1" + echo -e "\t ${CMSG}15${CEND}. eu-west-1 ${CMSG}16${CEND}. eu-west-2" + echo -e "\t ${CMSG}17${CEND}. eu-west-3 ${CMSG}18${CEND}. eu-north-1" + echo -e "\t ${CMSG}19${CEND}. sa-east-1 ${CMSG}20${CEND}. us-gov-east-1" + echo -e "\t ${CMSG}21${CEND}. us-gov-west-1" + read -e -p "Please input a number:(Default 1 press Enter) " Location + Location=${Location:-1} + if [[ "${Location}" =~ ^[1-9]$|^1[0-9]$|^2[0-1]$ ]]; then + break + else + echo "${CWARNING}input error! Please only input number 1~21${CEND}" + fi + done + [ "${Location}" == '1' ] && REGION='us-east-2' + [ "${Location}" == '2' ] && REGION='us-east-1' + [ "${Location}" == '3' ] && REGION='us-west-1' + [ "${Location}" == '4' ] && REGION='us-west-2' + [ "${Location}" == '5' ] && REGION='ap-south-1' + [ "${Location}" == '6' ] && REGION='ap-northeast-3' + [ "${Location}" == '7' ] && REGION='ap-northeast-2' + [ "${Location}" == '8' ] && REGION='ap-southeast-1' + [ "${Location}" == '9' ] && REGION='ap-southeast-2' + [ "${Location}" == '10' ] && REGION='ap-northeast-1' + [ "${Location}" == '11' ] && REGION='ca-central-1' + [ "${Location}" == '12' ] && REGION='cn-north-1' + [ "${Location}" == '13' ] && REGION='cn-northwest-1' + [ "${Location}" == '14' ] && REGION='eu-central-1' + [ "${Location}" == '15' ] && REGION='eu-west-1' + [ "${Location}" == '16' ] && REGION='eu-west-2' + [ "${Location}" == '17' ] && REGION='eu-west-3' + [ "${Location}" == '18' ] && REGION='eu-north-1' + [ "${Location}" == '19' ] && REGION='sa-east-1' + [ "${Location}" == '20' ] && REGION='us-gov-east-1' + [ "${Location}" == '21' ] && REGION='us-gov-west-1' + while :; do echo + read -e -p "Please enter the AWS Access Key: " ACCESS_KEY + [ -z "${ACCESS_KEY}" ] && continue + echo + read -e -p "Please enter the AWS Access Key: " SECRET_KEY + [ -z "${SECRET_KEY}" ] && continue + ${python_install_dir}/bin/s3cmd --access_key=${ACCESS_KEY} --secret_key=${SECRET_KEY} --region=${REGION} la > /dev/null 2>&1 + if [ $? -eq 0 ]; then + ${python_install_dir}/bin/s3cmd --configure --access_key=${ACCESS_KEY} --secret_key=${SECRET_KEY} --region=${REGION} --dump-config > ~/.s3cfg + echo "${CMSG}ACCESS_KEY/SECRET_KEY OK${CEND}" + while :; do echo + read -e -p "Please enter the Amazon S3 bucket: " S3_BUCKET + [ -z "${S3_BUCKET}" ] && continue + ${python_install_dir}/bin/s3cmd ls s3://${S3_BUCKET} > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "${CMSG}Bucket s3://${S3_BUCKET}/ existed${CEND}" + sed -i "s@^s3_bucket=.*@s3_bucket=${S3_BUCKET}@" ./config/options.conf + break + else + ${python_install_dir}/bin/s3cmd mb s3://${S3_BUCKET} > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "${CMSG}Bucket s3://${S3_BUCKET}/ created${CEND}" + sed -i "s@^s3_bucket=.*@s3_bucket=${S3_BUCKET}@" ./config/options.conf + break + else + echo "${CWARNING}The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.${CEND}" + continue + fi + fi + done + break + else + echo "${CWARNING}input error! ACCESS_KEY/SECRET_KEY invalid${CEND}" + continue + fi + done +fi + +if [ -n "`echo ${desc_bk} | grep -w 8`" ]; then + if [ ! -e "/usr/local/bin/dbxcli" ]; then + if [ "${armplatform}" == 'y' ]; then + wget -qc http://mirrors.linuxeye.com/oneinstack/src/dbxcli-linux-arm -O /usr/local/bin/dbxcli + else + wget -qc http://mirrors.linuxeye.com/oneinstack/src/dbxcli-linux-amd64 -O /usr/local/bin/dbxcli + fi + chmod +x /usr/local/bin/dbxcli + fi + while :; do echo + if dbxcli account; then + break + fi + done +fi diff --git a/bin/install.sh b/bin/install.sh new file mode 100644 index 0000000..55ad926 --- /dev/null +++ b/bin/install.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# ServerStack entry point. +# +# This script is now a THIN ENTRY POINT only. It bootstraps the environment +# and orchestrates the install workflow by calling main() from +# core/workflow.sh. All business logic (system detection, parameter +# parsing, menu, download, install, config, services, summary) has been moved +# into focused modules under lib/ (shared functions), core/ (orchestration) +# and modules/ (per-software installers). +# +# Usage and behavior are unchanged from the previous install.sh. + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin + +# Ensure cwd is the project root so all relative sources work exactly as before. +# oneinstack_dir is the project root (one level up from bin/); falling back to +# "$0" keeps this working even when readlink -f is unavailable. +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 + +# Load framework modules (function definitions only; nothing runs yet). +. ./lib/loader.sh +. ./lib/log.sh +. ./core/environment.sh +. ./core/init.sh +. ./core/argument.sh +. ./core/menu.sh +. ./core/validator.sh +. ./core/installer.sh +. ./core/service.sh +. ./core/summary.sh +. ./core/workflow.sh + +# Unified exception handling (cleanup / rollback on exit, interrupt, terminate). +# NOTE: ERR is intentionally NOT trapped. Binding ERR would fire trap_handler on +# every non-zero command (even benign ones outside if/&&/||) and auto-write an +# [ERROR] line to install.log, changing the original log output. Logging is done +# explicitly via log_error/error_exit; this trap only guarantees best-effort +# cleanup (currently no-ops) so the happy path and its logs stay faithful. +trap 'trap_handler' EXIT INT TERM + +# Run the install workflow. +main "$@" diff --git a/bin/pureftpd_vhost.sh b/bin/pureftpd_vhost.sh new file mode 100644 index 0000000..a05a44a --- /dev/null +++ b/bin/pureftpd_vhost.sh @@ -0,0 +1,271 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# FTP virtual user account management # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/options.conf +. ./lib/color.sh + +[ ! -d "${pureftpd_install_dir}" ] && { echo "${CFAILURE}FTP server does not exist! ${CEND}"; exit 1; } + +FTP_conf=${pureftpd_install_dir}/etc/pure-ftpd.conf +FTP_tmp_passfile=${pureftpd_install_dir}/etc/pureftpd_psss.tmp +Puredbfile=${pureftpd_install_dir}/etc/pureftpd.pdb +Passwdfile=${pureftpd_install_dir}/etc/pureftpd.passwd +FTP_bin=${pureftpd_install_dir}/bin/pure-pw +[ -z "`grep ^PureDB ${FTP_conf}`" ] && { echo "${CFAILURE}pure-ftpd is not own password database${CEND}" ; exit 1; } + +ARG_NUM=$# +Show_Help() { + echo + echo "Usage: $0 command ...[parameters].... + --help, -h Show this help message + --useradd,--add Add username + --usermod Modify directory + --passwd Modify password + --userdel,--delete Delete User + --listalluser,--list List all User + --showuser List User details + --username,-u [ftp username] Ftp username + --password,-p [ftp password] Ftp password + --directory,-d,-D [ftp directory] Ftp home directory + " +} + +TEMP=`getopt -o hu:p:d:D: --long help,useradd,add,usermod,passwd,userdel,delete,listalluser,list,showuser,username:,password:,directory: -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + --add|--useradd) + useradd_flag=y; shift 1 + ;; + --usermod) + usermod_flag=y; shift 1 + ;; + --passwd) + passwd_flag=y; shift 1 + ;; + --delete|--userdel) + userdel_flag=y; shift 1 + ;; + --list|--listalluser) + listalluser_flag=y; shift 1 + ;; + --showuser) + showuser_flag=y; shift 1 + ;; + -u|--username) + username_flag=y; User=$2; shift 2 + ;; + -p|--password) + password_flag=y; Password=$2; shift 2 + ;; + -d|-D|--directory) + directory_flag=y; Directory=$2; shift 2 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +USER() { + while :; do + if [ "${username_flag}" != 'y' ]; then + echo + read -e -p "Please input a username: " User + fi + if [ -z "${User}" ]; then + echo "${CWARNING}username can't be NULL! ${CEND}" + else + break + fi + done +} + +PASSWORD() { + while :; do + if [ "${password_flag}" != 'y' ]; then + echo + read -e -p "Please input the password: " Password + fi + [ -n "`echo ${Password} | grep '[+|&]'`" ] && { echo "${CWARNING}input error,not contain a plus sign (+) and &${CEND}"; continue; } + if (( ${#Password} >= 5 )); then + echo -e "${Password}\n${Password}" > ${FTP_tmp_passfile} + break + else + echo "${CWARNING}Ftp password least 5 characters! ${CEND}" + fi + done +} + +DIRECTORY() { + while :; do + if [ "${directory_flag}" != 'y' ]; then + echo + read -e -p "Please input the directory(Default directory: ${wwwroot_dir}): " Directory + fi + Directory=${Directory:-${wwwroot_dir}} + if [ ! -d "${Directory}" ]; then + echo "${CWARNING}The directory does not exist${CEND}" + else + break + fi + done +} + +UserAdd() { + USER + [ -e "${Passwdfile}" ] && [ -n "`grep ^${User}: ${Passwdfile}`" ] && { echo "${CQUESTION}[${User}] is already existed! ${CEND}"; exit 1; } + PASSWORD;DIRECTORY + ${FTP_bin} useradd ${User} -f ${Passwdfile} -u ${run_user} -g ${run_group} -d ${Directory} -m < ${FTP_tmp_passfile} + ${FTP_bin} mkdb ${Puredbfile} -f ${Passwdfile} > /dev/null 2>&1 + echo "#####################################" + echo + echo "[${User}] create successful! " + echo + echo "You user name is : ${CMSG}${User}${CEND}" + echo "You Password is : ${CMSG}${Password}${CEND}" + echo "You directory is : ${CMSG}${Directory}${CEND}" + echo +} + +UserMod() { + USER + [ -e "${Passwdfile}" ] && [ -z "`grep ^${User}: ${Passwdfile}`" ] && { echo "${CQUESTION}[${User}] was not existed! ${CEND}"; exit 1; } + DIRECTORY + ${FTP_bin} usermod ${User} -f ${Passwdfile} -d ${Directory} -m + ${FTP_bin} mkdb ${Puredbfile} -f ${Passwdfile} > /dev/null 2>&1 + echo "#####################################" + echo + echo "[${User}] modify a successful! " + echo + echo "You user name is : ${CMSG}${User}${CEND}" + echo "You new directory is : ${CMSG}${Directory}${CEND}" + echo +} + +UserPasswd() { + USER + [ -e "${Passwdfile}" ] && [ -z "`grep ^${User}: ${Passwdfile}`" ] && { echo "${CQUESTION}[${User}] was not existed! ${CEND}"; exit 1; } + PASSWORD + ${FTP_bin} passwd ${User} -f ${Passwdfile} -m < ${FTP_tmp_passfile} + ${FTP_bin} mkdb ${Puredbfile} -f ${Passwdfile} > /dev/null 2>&1 + echo "#####################################" + echo + echo "[${User}] Password changed successfully! " + echo + echo "You user name is : ${CMSG}${User}${CEND}" + echo "You new password is : ${CMSG}${Password}${CEND}" + echo +} + +UserDel() { + if [ ! -e "${Passwdfile}" ]; then + echo "${CQUESTION}User was not existed! ${CEND}" + else + ${FTP_bin} list + fi + + USER + [ -e "${Passwdfile}" ] && [ -z "`grep ^${User}: ${Passwdfile}`" ] && { echo "${CQUESTION}[${User}] was not existed! ${CEND}"; exit 1; } + ${FTP_bin} userdel ${User} -f ${Passwdfile} -m + ${FTP_bin} mkdb ${Puredbfile} -f ${Passwdfile} > /dev/null 2>&1 + echo + echo "[${User}] have been deleted! " +} + +ListAllUser() { + if [ ! -e "${Passwdfile}" ]; then + echo "${CQUESTION}User was not existed! ${CEND}" + else + ${FTP_bin} list + fi +} + +ShowUser() { + USER + [ -e "${Passwdfile}" ] && [ -z "`grep ^${User}: ${Passwdfile}`" ] && { echo "${CQUESTION}[${User}] was not existed! ${CEND}"; exit 1; } + ${FTP_bin} show ${User} +} + +Menu() { + while :; do + printf " +What Are You Doing? +\t${CMSG}1${CEND}. UserAdd +\t${CMSG}2${CEND}. UserMod +\t${CMSG}3${CEND}. UserPasswd +\t${CMSG}4${CEND}. UserDel +\t${CMSG}5${CEND}. ListAllUser +\t${CMSG}6${CEND}. ShowUser +\t${CMSG}q${CEND}. Exit +" + read -e -p "Please input the correct option: " Number + if [[ ! ${Number} =~ ^[1-6,q]$ ]]; then + echo "${CFAILURE}input error! Please only input 1~6 and q${CEND}" + else + case "${Number}" in + 1) + UserAdd + ;; + 2) + UserMod + ;; + 3) + UserPasswd + ;; + 4) + UserDel + ;; + 5) + ListAllUser + ;; + 6) + ShowUser + ;; + q) + exit + ;; + esac + fi + done +} + +if [ ${ARG_NUM} == 0 ]; then + Menu +else + [ "${useradd_flag}" == 'y' ] && UserAdd + [ "${usermod_flag}" == 'y' ] && UserMod + [ "${passwd_flag}" == 'y' ] && UserPasswd + [ "${userdel_flag}" == 'y' ] && UserDel + [ "${listalluser_flag}" == 'y' ] && ListAllUser + [ "${showuser_flag}" == 'y' ] && ShowUser +fi diff --git a/bin/reset_db_root_password.sh b/bin/reset_db_root_password.sh new file mode 100644 index 0000000..7f50833 --- /dev/null +++ b/bin/reset_db_root_password.sh @@ -0,0 +1,145 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# Reset Database root password for OneinStack # +# For more information please visit https://oneinstack.com # +####################################################################### +" +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/options.conf +. ./lib/color.sh +. ./lib/check_dir.sh +[ ! -d "${db_install_dir}" ] && { echo "${CFAILURE}Database is not installed on your system! ${CEND}"; exit 1; } + +Show_Help() { + echo "Usage: $0 command ...[parameters].... + -h, --help print this help. + -q, --quiet quiet operation. + -f, --force Lost Database Password? Forced reset password. + -p, --password [pass] DB super password. + " +} + +New_dbrootpwd="`< /dev/urandom tr -dc A-Za-z0-9 | head -c8`" +TEMP=`getopt -o hqfp: --long help,quiet,force,password: -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + -q|--quiet) + quiet_flag=y; shift 1 + ;; + -f|--force) + force_flag=y; shift 1 + ;; + -p|--password) + New_dbrootpwd=$2; shift 2 + password_flag=y + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +Input_dbrootpwd() { + while :; do echo + read -e -p "Please input the root password of database: " New_dbrootpwd + [ -n "`echo ${New_dbrootpwd} | grep '[+|&]'`" ] && { echo "${CWARNING}input error,not contain a plus sign (+) and &${CEND}"; continue; } + (( ${#New_dbrootpwd} >= 5 )) && break || echo "${CWARNING}database root password least 5 characters! ${CEND}" + done +} + +Reset_Interaction_dbrootpwd() { + ${db_install_dir}/bin/mysqladmin -uroot -p"${dbrootpwd}" password "${New_dbrootpwd}" -h localhost > /dev/null 2>&1 + status_Localhost=`echo $?` + ${db_install_dir}/bin/mysqladmin -uroot -p"${dbrootpwd}" password "${New_dbrootpwd}" -h 127.0.0.1 > /dev/null 2>&1 + status_127=`echo $?` + if [ ${status_Localhost} == '0' -a ${status_127} == '0' ]; then + sed -i "s+^dbrootpwd.*+dbrootpwd='${New_dbrootpwd}'+" ./config/options.conf + echo + echo "Password reset succesfully! " + echo "The new password: ${CMSG}${New_dbrootpwd}${CEND}" + echo + else + echo "${CFAILURE}Reset Database root password failed! ${CEND}" + fi +} + +Reset_force_dbrootpwd() { + DB_Ver="`${db_install_dir}/bin/mysql_config --version`" + echo "${CMSG}Stopping MySQL...${CEND}" + service mysqld stop > /dev/null 2>&1 + while [ -n "`ps -ef | grep mysqld | grep -v grep | awk '{print $2}'`" ]; do + sleep 1 + done + echo "${CMSG}skip grant tables...${CEND}" + ${db_install_dir}/bin/mysqld_safe --skip-grant-tables > /dev/null 2>&1 & + sleep 5 + while [ -z "`ps -ef | grep 'mysqld ' | grep -v grep | awk '{print $2}'`" ]; do + sleep 1 + done + if echo "${DB_Ver}" | grep -Eqi '^8.0.|^5.7.|^10.2.'; then + ${db_install_dir}/bin/mysql -uroot -hlocalhost << EOF +flush privileges; +alter user 'root'@'localhost' identified by "${New_dbrootpwd}"; +alter user 'root'@'127.0.0.1' identified by "${New_dbrootpwd}"; +EOF + else + ${db_install_dir}/bin/mysql -uroot -hlocalhost << EOF +update mysql.user set password = Password("${New_dbrootpwd}") where User = 'root'; +EOF + fi + if [ $? -eq 0 ]; then + killall mysqld + while [ -n "`ps -ef | grep mysqld | grep -v grep | awk '{print $2}'`" ]; do + sleep 1 + done + [ -n "`ps -ef | grep mysqld | grep -v grep | awk '{print $2}'`" ] && ps -ef | grep mysqld | grep -v grep | awk '{print $2}' | xargs kill -9 > /dev/null 2>&1 + service mysqld start > /dev/null 2>&1 + sed -i "s+^dbrootpwd.*+dbrootpwd='${New_dbrootpwd}'+" ./config/options.conf + [ -e ~/ReadMe ] && sed -i "s+^MySQL root password:.*+MySQL root password: ${New_dbrootpwd}+" ~/ReadMe + echo + echo "Password reset succesfully! " + echo "The new password: ${CMSG}${New_dbrootpwd}${CEND}" + echo + fi +} + +[ "${password_flag}" == 'y' ] && quiet_flag=y +if [ "${quiet_flag}" == 'y' ]; then + if [ "${force_flag}" == 'y' ]; then + Reset_force_dbrootpwd + else + sleep 2 && [ ! -e /tmp/mysql.sock ] && service mysqld start + Reset_Interaction_dbrootpwd + fi +else + Input_dbrootpwd + if [ "${force_flag}" == 'y' ]; then + Reset_force_dbrootpwd + else + Reset_Interaction_dbrootpwd + fi +fi +popd > /dev/null diff --git a/bin/uninstall.sh b/bin/uninstall.sh new file mode 100644 index 0000000..7ee9501 --- /dev/null +++ b/bin/uninstall.sh @@ -0,0 +1,686 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# Uninstall OneinStack # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/options.conf +. ./lib/color.sh +. ./lib/get_char.sh +. ./lib/check_dir.sh + +Show_Help() { + echo + echo "Usage: $0 command ...[parameters].... + --help, -h Show this help message, More: https://oneinstack.com + --quiet, -q quiet operation + --all Uninstall All + --web Uninstall Nginx + --mysql Uninstall MySQL/MariaDB + --postgresql Uninstall PostgreSQL + --mongodb Uninstall MongoDB + --php Uninstall PHP (PATH: ${php_install_dir}) + --mphp_ver [53~81] Uninstall another PHP version (PATH: ${php_install_dir}\${mphp_ver}) + --allphp Uninstall all PHP + --phpcache Uninstall PHP opcode cache + --php_extensions [ext name] Uninstall PHP extensions, include zendguardloader,ioncube, + sourceguardian,imagick,gmagick,fileinfo,imap,ldap,calendar,phalcon, + yaf,yar,redis,mongodb,swoole,xdebug + --pureftpd Uninstall PureFtpd + --redis Uninstall Redis-server + --phpmyadmin Uninstall phpMyAdmin + --python Uninstall Python (PATH: ${python_install_dir}) + --node Uninstall Nodejs (PATH: ${nodejs_install_dir}) + " +} + +ARG_NUM=$# +TEMP=`getopt -o hvVq --long help,version,quiet,all,web,mysql,postgresql,mongodb,php,mphp_ver:,allphp,phpcache,php_extensions:,pureftpd,redis,phpmyadmin,python,node -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + -q|--quiet) + quiet_flag=y + uninstall_flag=y + shift 1 + ;; + --all) + all_flag=y + web_flag=y + mysql_flag=y + postgresql_flag=y + mongodb_flag=y + allphp_flag=y + nodejs_flag=y + pureftpd_flag=y + redis_flag=y + phpmyadmin_flag=y + python_flag=y + shift 1 + ;; + --web) + web_flag=y; shift 1 + ;; + --mysql) + mysql_flag=y; shift 1 + ;; + --postgresql) + postgresql_flag=y; shift 1 + ;; + --mongodb) + mongodb_flag=y; shift 1 + ;; + --php) + php_flag=y; shift 1 + ;; + --mphp_ver) + mphp_ver=$2; mphp_flag=y; shift 2 + [[ ! "${mphp_ver}" =~ ^5[3-6]$|^7[0-4]$|^8[0-1]$ ]] && { echo "${CWARNING}mphp_ver input error! Please only input number 53~81${CEND}"; exit 1; } + ;; + --allphp) + allphp_flag=y; shift 1 + ;; + --phpcache) + phpcache_flag=y; shift 1 + ;; + --php_extensions) + php_extensions=$2; shift 2 + [ -n "`echo ${php_extensions} | grep -w zendguardloader`" ] && pecl_zendguardloader=1 + [ -n "`echo ${php_extensions} | grep -w ioncube`" ] && pecl_ioncube=1 + [ -n "`echo ${php_extensions} | grep -w sourceguardian`" ] && pecl_sourceguardian=1 + [ -n "`echo ${php_extensions} | grep -w imagick`" ] && pecl_imagick=1 + [ -n "`echo ${php_extensions} | grep -w gmagick`" ] && pecl_gmagick=1 + [ -n "`echo ${php_extensions} | grep -w fileinfo`" ] && pecl_fileinfo=1 + [ -n "`echo ${php_extensions} | grep -w imap`" ] && pecl_imap=1 + [ -n "`echo ${php_extensions} | grep -w ldap`" ] && pecl_ldap=1 + [ -n "`echo ${php_extensions} | grep -w calendar`" ] && pecl_calendar=1 + [ -n "`echo ${php_extensions} | grep -w phalcon`" ] && pecl_phalcon=1 + [ -n "`echo ${php_extensions} | grep -w yaf`" ] && pecl_yaf=1 + [ -n "`echo ${php_extensions} | grep -w yar`" ] && pecl_yar=1 + [ -n "`echo ${php_extensions} | grep -w redis`" ] && pecl_redis=1 + [ -n "`echo ${php_extensions} | grep -w mongodb`" ] && pecl_mongodb=1 + [ -n "`echo ${php_extensions} | grep -w swoole`" ] && pecl_swoole=1 + [ -n "`echo ${php_extensions} | grep -w xdebug`" ] && pecl_xdebug=1 + ;; + --node) + nodejs_flag=y; shift 1 + ;; + --pureftpd) + pureftpd_flag=y; shift 1 + ;; + --redis) + redis_flag=y; shift 1 + ;; + --phpmyadmin) + phpmyadmin_flag=y; shift 1 + ;; + --python) + python_flag=y; shift 1 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +Uninstall_status() { + if [ "${quiet_flag}" != 'y' ]; then + while :; do echo + read -e -p "Do you want to uninstall? [y/n]: " uninstall_flag + if [[ ! ${uninstall_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + fi +} + +Print_Warn() { + echo + echo "${CWARNING}You will uninstall OneinStack, Please backup your configure files and DB data! ${CEND}" +} + +Print_web() { + [ -d "${nginx_install_dir}" ] && echo ${nginx_install_dir} + [ -e "/etc/services/nginx" ] && echo /etc/services/nginx + [ -e "/lib/systemd/system/nginx.service" ] && echo /lib/systemd/system/nginx.service + [ -e "/etc/logrotate.d/nginx" ] && echo /etc/logrotate.d/nginx +} + +Uninstall_Web() { + [ -d "${nginx_install_dir}" ] && { killall nginx > /dev/null 2>&1; rm -rf ${nginx_install_dir} /etc/services/nginx /etc/logrotate.d/nginx; sed -i "s@${nginx_install_dir}/sbin:@@" /etc/profile; echo "${CMSG}Nginx uninstall completed! ${CEND}"; } + [ -e "/lib/systemd/system/nginx.service" ] && { systemctl disable nginx > /dev/null 2>&1; rm -f /lib/systemd/system/nginx.service; } + [ -e "${wwwroot_dir}" ] && /bin/mv ${wwwroot_dir}{,$(date +%Y%m%d%H)} + sed -i 's@^website_name=.*@website_name=@' ./config/options.conf + sed -i 's@^backup_content=.*@backup_content=@' ./config/options.conf +} + +Print_MySQL() { + [ -e "${db_install_dir}" ] && echo ${db_install_dir} + [ -e "/etc/init.d/mysqld" ] && echo /etc/init.d/mysqld + [ -e "/etc/my.cnf" ] && echo /etc/my.cnf +} + +Print_PostgreSQL() { + [ -e "${pgsql_install_dir}" ] && echo ${pgsql_install_dir} + [ -e "/etc/services/postgresql" ] && echo /etc/services/postgresql + [ -e "/lib/systemd/system/postgresql.service" ] && echo /lib/systemd/system/postgresql.service +} + +Print_MongoDB() { + [ -e "${mongo_install_dir}" ] && echo ${mongo_install_dir} + [ -e "/etc/services/mongod" ] && echo /etc/services/mongod + [ -e "/lib/systemd/system/mongod.service" ] && echo /lib/systemd/system/mongod.service + [ -e "/etc/mongod.conf" ] && echo /etc/mongod.conf +} + +Uninstall_MySQL() { + # uninstall mysql,mariadb + if [ -d "${db_install_dir}/support-files" ]; then + service mysqld stop > /dev/null 2>&1 + rm -rf ${db_install_dir} /etc/init.d/mysqld /etc/my.cnf* /etc/ld.so.conf.d/*{mysql,mariadb}*.conf + id -u mysql >/dev/null 2>&1 ; [ $? -eq 0 ] && userdel mysql + [ -e "${db_data_dir}" ] && /bin/mv ${db_data_dir}{,$(date +%Y%m%d%H)} + sed -i 's@^dbrootpwd=.*@dbrootpwd=@' ./config/options.conf + sed -i "s@${db_install_dir}/bin:@@" /etc/profile + echo "${CMSG}MySQL uninstall completed! ${CEND}" + fi +} + +Uninstall_PostgreSQL() { + # uninstall postgresql + if [ -e "${pgsql_install_dir}/bin/psql" ]; then + service postgresql stop > /dev/null 2>&1 + rm -rf ${pgsql_install_dir} /etc/services/postgresql + [ -e "/lib/systemd/system/postgresql.service" ] && { systemctl disable postgresql > /dev/null 2>&1; rm -f /lib/systemd/system/postgresql.service; } + [ -e "${php_install_dir}/etc/php.d/07-pgsql.ini" ] && rm -f ${php_install_dir}/etc/php.d/07-pgsql.ini + id -u postgres >/dev/null 2>&1 ; [ $? -eq 0 ] && userdel postgres + [ -e "${pgsql_data_dir}" ] && /bin/mv ${pgsql_data_dir}{,$(date +%Y%m%d%H)} + sed -i 's@^dbpostgrespwd=.*@dbpostgrespwd=@' ./config/options.conf + sed -i "s@${pgsql_install_dir}/bin:@@" /etc/profile + echo "${CMSG}PostgreSQL uninstall completed! ${CEND}" + fi +} + +Uninstall_MongoDB() { + # uninstall mongodb + if [ -e "${mongo_install_dir}/bin/mongo" ]; then + service mongod stop > /dev/null 2>&1 + rm -rf ${mongo_install_dir} /etc/mongod.conf /etc/services/mongod /tmp/mongo*.sock + [ -e "/lib/systemd/system/mongod.service" ] && { systemctl disable mongod > /dev/null 2>&1; rm -f /lib/systemd/system/mongod.service; } + [ -e "${php_install_dir}/etc/php.d/07-mongo.ini" ] && rm -f ${php_install_dir}/etc/php.d/07-mongo.ini + [ -e "${php_install_dir}/etc/php.d/07-mongodb.ini" ] && rm -f ${php_install_dir}/etc/php.d/07-mongodb.ini + id -u mongod > /dev/null 2>&1 ; [ $? -eq 0 ] && userdel mongod + [ -e "${mongo_data_dir}" ] && /bin/mv ${mongo_data_dir}{,$(date +%Y%m%d%H)} + sed -i 's@^dbmongopwd=.*@dbmongopwd=@' ./config/options.conf + sed -i "s@${mongo_install_dir}/bin:@@" /etc/profile + echo "${CMSG}MongoDB uninstall completed! ${CEND}" + fi +} + +Print_PHP() { + [ -e "${php_install_dir}" ] && echo ${php_install_dir} + [ -e "/etc/services/php-fpm" ] && echo /etc/services/php-fpm + [ -e "/lib/systemd/system/php-fpm.service" ] && echo /lib/systemd/system/php-fpm.service +} + +Print_MPHP() { + [ -e "${php_install_dir}${mphp_ver}" ] && echo ${php_install_dir}${mphp_ver} + [ -e "/etc/services/php${mphp_ver}-fpm" ] && echo /etc/services/php${mphp_ver}-fpm + [ -e "/lib/systemd/system/php${mphp_ver}-fpm.service" ] && echo /lib/systemd/system/php${mphp_ver}-fpm.service +} + +Print_ALLPHP() { + [ -e "${php_install_dir}" ] && echo ${php_install_dir} + [ -e "/etc/services/php-fpm" ] && echo /etc/services/php-fpm + [ -e "/lib/systemd/system/php-fpm.service" ] && echo /lib/systemd/system/php-fpm.service + for php_ver in 53 54 55 56 70 71 72 73 74 80 81; do + [ -e "${php_install_dir}${php_ver}" ] && echo ${php_install_dir}${php_ver} + [ -e "/etc/services/php${php_ver}-fpm" ] && echo /etc/services/php${php_ver}-fpm + [ -e "/lib/systemd/system/php${php_ver}-fpm.service" ] && echo /lib/systemd/system/php${php_ver}-fpm.service + done + [ -e "${imagick_install_dir}" ] && echo ${imagick_install_dir} + [ -e "${gmagick_install_dir}" ] && echo ${gmagick_install_dir} + [ -e "${curl_install_dir}" ] && echo ${curl_install_dir} + [ -e "${freetype_install_dir}" ] && echo ${freetype_install_dir} +} + +Uninstall_PHP() { + [ -e "/etc/services/php-fpm" ] && { service php-fpm stop > /dev/null 2>&1; rm -f /etc/services/php-fpm; } + [ -e "/lib/systemd/system/php-fpm.service" ] && { systemctl stop php-fpm > /dev/null 2>&1; systemctl disable php-fpm > /dev/null 2>&1; rm -f /lib/systemd/system/php-fpm.service; } + [ -e "${php_install_dir}" ] && { rm -rf ${php_install_dir}; echo "${CMSG}PHP uninstall completed! ${CEND}"; } + sed -i "s@${php_install_dir}/bin:@@" /etc/profile +} + +Uninstall_MPHP() { + [ -e "/etc/services/php${mphp_ver}-fpm" ] && { service php${mphp_ver}-fpm stop > /dev/null 2>&1; rm -f /etc/services/php${mphp_ver}-fpm; } + [ -e "/lib/systemd/system/php${mphp_ver}-fpm.service" ] && { systemctl stop php${mphp_ver}-fpm > /dev/null 2>&1; systemctl disable php${mphp_ver}-fpm > /dev/null 2>&1; rm -f /lib/systemd/system/php${mphp_ver}-fpm.service; } + [ -e "${php_install_dir}${mphp_ver}" ] && { rm -rf ${php_install_dir}${mphp_ver}; echo "${CMSG}PHP${mphp_ver} uninstall completed! ${CEND}"; } +} + +Uninstall_ALLPHP() { + [ -e "/etc/services/php-fpm" ] && { service php-fpm stop > /dev/null 2>&1; rm -f /etc/services/php-fpm; } + [ -e "/lib/systemd/system/php-fpm.service" ] && { systemctl stop php-fpm > /dev/null 2>&1; systemctl disable php-fpm > /dev/null 2>&1; rm -f /lib/systemd/system/php-fpm.service; } + [ -e "${php_install_dir}" ] && { rm -rf ${php_install_dir}; echo "${CMSG}PHP uninstall completed! ${CEND}"; } + sed -i "s@${php_install_dir}/bin:@@" /etc/profile + for php_ver in 53 54 55 56 70 71 72 73 74 80 81; do + [ -e "/etc/services/php${php_ver}-fpm" ] && { service php${php_ver}-fpm stop > /dev/null 2>&1; rm -f /etc/services/php${php_ver}-fpm; } + [ -e "/lib/systemd/system/php${php_ver}-fpm.service" ] && { systemctl stop php${php_ver}-fpm > /dev/null 2>&1; systemctl disable php${php_ver}-fpm > /dev/null 2>&1; rm -f /lib/systemd/system/php${php_ver}-fpm.service; } + [ -e "${php_install_dir}${php_ver}" ] && { rm -rf ${php_install_dir}${php_ver}; echo "${CMSG}PHP${php_ver} uninstall completed! ${CEND}"; } + done + [ -e "${imagick_install_dir}" ] && rm -rf ${imagick_install_dir} + [ -e "${gmagick_install_dir}" ] && rm -rf ${gmagick_install_dir} + [ -e "${curl_install_dir}" ] && rm -rf ${curl_install_dir} + [ -e "${freetype_install_dir}" ] && rm -rf ${freetype_install_dir} +} + +Uninstall_PHPcache() { + . modules/php-addons/zendopcache.sh + . modules/php-addons/xcache.sh + . modules/php-addons/apcu.sh + . modules/php-addons/eaccelerator.sh + Uninstall_ZendOPcache + Uninstall_XCache + Uninstall_APCU + Uninstall_eAccelerator + # reload php + [ -e "${php_install_dir}/sbin/php-fpm" ] && { [ -e "/bin/systemctl" ] && systemctl reload php-fpm || service php-fpm reload; } + [ -n "${mphp_ver}" -a -e "${php_install_dir}${mphp_ver}/sbin/php-fpm" ] && { [ -e "/bin/systemctl" ] && systemctl reload php${mphp_ver}-fpm || service php${mphp_ver}-fpm reload; } +} + +Uninstall_PHPext() { + # ZendGuardLoader + if [ "${pecl_zendguardloader}" == '1' ]; then + . modules/php-addons/ZendGuardLoader.sh + Uninstall_ZendGuardLoader + fi + + # ioncube + if [ "${pecl_ioncube}" == '1' ]; then + . modules/php-addons/ioncube.sh + Uninstall_ionCube + fi + + # SourceGuardian + if [ "${pecl_sourceguardian}" == '1' ]; then + . modules/php-addons/sourceguardian.sh + Uninstall_SourceGuardian + fi + + # imagick + if [ "${pecl_imagick}" == '1' ]; then + . modules/image/ImageMagick.sh + Uninstall_ImageMagick + Uninstall_pecl_imagick + fi + + # gmagick + if [ "${pecl_gmagick}" == '1' ]; then + . modules/image/GraphicsMagick.sh + Uninstall_GraphicsMagick + Uninstall_pecl_gmagick + fi + + # fileinfo + if [ "${pecl_fileinfo}" == '1' ]; then + . modules/php-addons/pecl_fileinfo.sh + Uninstall_pecl_fileinfo + fi + + # imap + if [ "${pecl_imap}" == '1' ]; then + . modules/php-addons/pecl_imap.sh + Uninstall_pecl_imap + fi + + # ldap + if [ "${pecl_ldap}" == '1' ]; then + . modules/php-addons/pecl_ldap.sh + Uninstall_pecl_ldap + fi + + # calendar + if [ "${pecl_calendar}" == '1' ]; then + . modules/php-addons/pecl_calendar.sh + Uninstall_pecl_calendar + fi + + # phalcon + if [ "${pecl_phalcon}" == '1' ]; then + . modules/php-addons/pecl_phalcon.sh + Uninstall_pecl_phalcon + fi + + # yaf + if [ "${pecl_yaf}" == '1' ]; then + . modules/php-addons/pecl_yaf.sh + Uninstall_pecl_yaf 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + fi + + # yar + if [ "${pecl_yar}" == '1' ]; then + . modules/php-addons/pecl_yar.sh + Uninstall_pecl_yar 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + fi + + # pecl_redis + if [ "${pecl_redis}" == '1' ]; then + . modules/cache/redis.sh + Uninstall_pecl_redis + fi + + # pecl_mongodb + if [ "${pecl_mongodb}" == '1' ]; then + . modules/php-addons/pecl_mongodb.sh + Uninstall_pecl_mongodb + fi + + # swoole + if [ "${pecl_swoole}" == '1' ]; then + . modules/php-addons/pecl_swoole.sh + Uninstall_pecl_swoole + fi + + # xdebug + if [ "${pecl_xdebug}" == '1' ]; then + . modules/php-addons/pecl_xdebug.sh + Uninstall_pecl_xdebug + fi + + # reload php + [ -e "${php_install_dir}/sbin/php-fpm" ] && { [ -e "/bin/systemctl" ] && systemctl reload php-fpm || service php-fpm reload; } + [ -n "${mphp_ver}" -a -e "${php_install_dir}${mphp_ver}/sbin/php-fpm" ] && { [ -e "/bin/systemctl" ] && systemctl reload php${mphp_ver}-fpm || service php${mphp_ver}-fpm reload; } +} + +Menu_PHPext() { + while :; do + echo 'Please select uninstall PHP extensions:' + echo -e "\t${CMSG} 0${CEND}. Do not uninstall" + echo -e "\t${CMSG} 1${CEND}. Uninstall zendguardloader(PHP<=5.6)" + echo -e "\t${CMSG} 2${CEND}. Uninstall ioncube" + echo -e "\t${CMSG} 3${CEND}. Uninstall sourceguardian(PHP<=7.2)" + echo -e "\t${CMSG} 4${CEND}. Uninstall imagick" + echo -e "\t${CMSG} 5${CEND}. Uninstall gmagick" + echo -e "\t${CMSG} 6${CEND}. Uninstall fileinfo" + echo -e "\t${CMSG} 7${CEND}. Uninstall imap" + echo -e "\t${CMSG} 8${CEND}. Uninstall ldap" + echo -e "\t${CMSG} 9${CEND}. Uninstall phalcon(PHP>=5.5)" + echo -e "\t${CMSG}10${CEND}. Uninstall redis" + echo -e "\t${CMSG}11${CEND}. Uninstall mongodb" + echo -e "\t${CMSG}12${CEND}. Uninstall swoole" + echo -e "\t${CMSG}13${CEND}. Uninstall xdebug(PHP>=5.5)" + read -e -p "Please input a number:(Default 0 press Enter) " phpext_option + phpext_option=${phpext_option:-0} + [ "${phpext_option}" == '0' ] && break + array_phpext=(${phpext_option}) + array_all=(1 2 3 4 5 6 7 8 9 10 11 12 13) + for v in ${array_phpext[@]} + do + [ -z "`echo ${array_all[@]} | grep -w ${v}`" ] && phpext_flag=1 + done + if [ "${phpext_flag}" == '1' ]; then + unset phpext_flag + echo; echo "${CWARNING}input error! Please only input number 1 2 3 14 and so on${CEND}"; echo + continue + else + [ -n "`echo ${array_phpext[@]} | grep -w 1`" ] && pecl_zendguardloader=1 + [ -n "`echo ${array_phpext[@]} | grep -w 2`" ] && pecl_ioncube=1 + [ -n "`echo ${array_phpext[@]} | grep -w 3`" ] && pecl_sourceguardian=1 + [ -n "`echo ${array_phpext[@]} | grep -w 4`" ] && pecl_imagick=1 + [ -n "`echo ${array_phpext[@]} | grep -w 5`" ] && pecl_gmagick=1 + [ -n "`echo ${array_phpext[@]} | grep -w 6`" ] && pecl_fileinfo=1 + [ -n "`echo ${array_phpext[@]} | grep -w 7`" ] && pecl_imap=1 + [ -n "`echo ${array_phpext[@]} | grep -w 8`" ] && pecl_ldap=1 + [ -n "`echo ${array_phpext[@]} | grep -w 9`" ] && pecl_phalcon=1 + [ -n "`echo ${array_phpext[@]} | grep -w 10`" ] && pecl_redis=1 + [ -n "`echo ${array_phpext[@]} | grep -w 11`" ] && pecl_mongodb=1 + [ -n "`echo ${array_phpext[@]} | grep -w 12`" ] && pecl_swoole=1 + [ -n "`echo ${array_phpext[@]} | grep -w 13`" ] && pecl_xdebug=1 + break + fi + done +} + +Print_PureFtpd() { + [ -e "${pureftpd_install_dir}" ] && echo ${pureftpd_install_dir} + [ -e "/etc/services/pureftpd" ] && echo /etc/services/pureftpd + [ -e "/lib/systemd/system/pureftpd.service" ] && echo /lib/systemd/system/pureftpd.service +} + +Uninstall_PureFtpd() { + [ -e "${pureftpd_install_dir}" ] && { service pureftpd stop > /dev/null 2>&1; rm -rf ${pureftpd_install_dir} /etc/services/pureftpd; echo "${CMSG}Pureftpd uninstall completed! ${CEND}"; } + [ -e "/lib/systemd/system/pureftpd.service" ] && { systemctl disable pureftpd > /dev/null 2>&1; rm -f /lib/systemd/system/pureftpd.service; } +} + +Print_Redis_server() { + [ -e "${redis_install_dir}" ] && echo ${redis_install_dir} + [ -e "/etc/services/redis-server" ] && echo /etc/services/redis-server + [ -e "/lib/systemd/system/redis-server.service" ] && echo /lib/systemd/system/redis-server.service +} + +Uninstall_Redis_server() { + [ -e "${redis_install_dir}" ] && { service redis-server stop > /dev/null 2>&1; rm -rf ${redis_install_dir} /etc/services/redis-server /usr/local/bin/redis-*; echo "${CMSG}Redis uninstall completed! ${CEND}"; } + [ -e "/lib/systemd/system/redis-server.service" ] && { systemctl disable redis-server > /dev/null 2>&1; rm -f /lib/systemd/system/redis-server.service; } +} + +Print_phpMyAdmin() { + [ -d "${wwwroot_dir}/default/phpMyAdmin" ] && echo ${wwwroot_dir}/default/phpMyAdmin +} + +Uninstall_phpMyAdmin() { + [ -d "${wwwroot_dir}/default/phpMyAdmin" ] && rm -rf ${wwwroot_dir}/default/phpMyAdmin +} + +Print_openssl() { + [ -d "${openssl_install_dir}" ] && echo ${openssl_install_dir} +} + +Uninstall_openssl() { + [ -d "${openssl_install_dir}" ] && rm -rf ${openssl_install_dir} +} + +Print_Python() { + [ -d "${python_install_dir}" ] && echo ${python_install_dir} +} + +Print_Nodejs() { + [ -e "${nodejs_install_dir}" ] && echo ${nodejs_install_dir} + [ -e "/etc/profile.d/nodejs.sh" ] && echo /etc/profile.d/nodejs.sh +} + +Menu() { +while :; do + printf " +What Are You Doing? +\t${CMSG} 0${CEND}. Uninstall All +\t${CMSG} 1${CEND}. Uninstall Nginx +\t${CMSG} 2${CEND}. Uninstall MySQL/MariaDB +\t${CMSG} 3${CEND}. Uninstall PostgreSQL +\t${CMSG} 4${CEND}. Uninstall MongoDB +\t${CMSG} 5${CEND}. Uninstall all PHP +\t${CMSG} 6${CEND}. Uninstall PHP opcode cache +\t${CMSG} 7${CEND}. Uninstall PHP extensions +\t${CMSG} 8${CEND}. Uninstall PureFtpd +\t${CMSG} 9${CEND}. Uninstall Redis +\t${CMSG}10${CEND}. Uninstall phpMyAdmin +\t${CMSG}11${CEND}. Uninstall Python (PATH: ${python_install_dir}) +\t${CMSG}12${CEND}. Uninstall Nodejs (PATH: ${nodejs_install_dir}) +\t${CMSG} q${CEND}. Exit +" + echo + read -e -p "Please input the correct option: " Number + if [[ ! "${Number}" =~ ^[0-9,q]$|^1[0-2]$ ]]; then + echo "${CWARNING}input error! Please only input 0~12 and q${CEND}" + else + case "$Number" in + 0) + Print_Warn + Print_web + Print_MySQL + Print_PostgreSQL + Print_MongoDB + Print_ALLPHP + Print_PureFtpd + Print_Redis_server + Print_openssl + Print_phpMyAdmin + Print_Python + Print_Nodejs + Uninstall_status + if [ "${uninstall_flag}" == 'y' ]; then + Uninstall_Web + Uninstall_MySQL + Uninstall_PostgreSQL + Uninstall_MongoDB + Uninstall_ALLPHP + Uninstall_PureFtpd + Uninstall_Redis_server + Uninstall_openssl + Uninstall_phpMyAdmin + . modules/lang/python.sh; Uninstall_Python + . modules/lang/nodejs.sh; Uninstall_Nodejs + else + exit + fi + ;; + 1) + Print_Warn + Print_web + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_Web || exit + ;; + 2) + Print_Warn + Print_MySQL + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_MySQL || exit + ;; + 3) + Print_Warn + Print_PostgreSQL + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_PostgreSQL || exit + ;; + 4) + Print_Warn + Print_MongoDB + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_MongoDB || exit + ;; + 5) + Print_ALLPHP + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_ALLPHP || exit + ;; + 6) + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_PHPcache || exit + ;; + 7) + Menu_PHPext + [ "${phpext_option}" != '0' ] && Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_PHPext || exit + ;; + 8) + Print_PureFtpd + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_PureFtpd || exit + ;; + 9) + Print_Redis_server + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_Redis_server || exit + ;; + 10) + Print_phpMyAdmin + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && Uninstall_phpMyAdmin || exit + ;; + 11) + Print_Python + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && { . modules/lang/python.sh; Uninstall_Python; } || exit + ;; + 12) + Print_Nodejs + Uninstall_status + [ "${uninstall_flag}" == 'y' ] && { . modules/lang/nodejs.sh; Uninstall_Nodejs; } || exit + ;; + q) + exit + ;; + esac + fi +done +} + +if [ ${ARG_NUM} == 0 ]; then + Menu +else + [ "${web_flag}" == 'y' ] && Print_web + [ "${mysql_flag}" == 'y' ] && Print_MySQL + [ "${postgresql_flag}" == 'y' ] && Print_PostgreSQL + [ "${mongodb_flag}" == 'y' ] && Print_MongoDB + if [ "${allphp_flag}" == 'y' ]; then + Print_ALLPHP + else + [ "${php_flag}" == 'y' ] && Print_PHP + [ "${mphp_flag}" == 'y' ] && [ "${phpcache_flag}" != 'y' ] && [ -z "${php_extensions}" ] && Print_MPHP + fi + [ "${pureftpd_flag}" == 'y' ] && Print_PureFtpd + [ "${redis_flag}" == 'y' ] && Print_Redis_server + [ "${phpmyadmin_flag}" == 'y' ] && Print_phpMyAdmin + [ "${python_flag}" == 'y' ] && Print_Python + [ "${nodejs_flag}" == 'y' ] && Print_Nodejs + [ "${all_flag}" == 'y' ] && Print_openssl + Uninstall_status + if [ "${uninstall_flag}" == 'y' ]; then + [ "${web_flag}" == 'y' ] && Uninstall_Web + [ "${mysql_flag}" == 'y' ] && Uninstall_MySQL + [ "${postgresql_flag}" == 'y' ] && Uninstall_PostgreSQL + [ "${mongodb_flag}" == 'y' ] && Uninstall_MongoDB + if [ "${allphp_flag}" == 'y' ]; then + Uninstall_ALLPHP + else + [ "${php_flag}" == 'y' ] && Uninstall_PHP + [ "${phpcache_flag}" == 'y' ] && Uninstall_PHPcache + [ -n "${php_extensions}" ] && Uninstall_PHPext + [ "${mphp_flag}" == 'y' ] && [ "${phpcache_flag}" != 'y' ] && [ -z "${php_extensions}" ] && Uninstall_MPHP + [ "${mphp_flag}" == 'y' ] && [ "${phpcache_flag}" == 'y' ] && { php_install_dir=${php_install_dir}${mphp_ver}; Uninstall_PHPcache; } + [ "${mphp_flag}" == 'y' ] && [ -n "${php_extensions}" ] && { php_install_dir=${php_install_dir}${mphp_ver}; Uninstall_PHPext; } + fi + [ "${pureftpd_flag}" == 'y' ] && Uninstall_PureFtpd + [ "${redis_flag}" == 'y' ] && Uninstall_Redis_server + [ "${phpmyadmin_flag}" == 'y' ] && Uninstall_phpMyAdmin + [ "${python_flag}" == 'y' ] && { . modules/lang/python.sh; Uninstall_Python; } + [ "${nodejs_flag}" == 'y' ] && { . modules/lang/nodejs.sh; Uninstall_Nodejs; } + [ "${all_flag}" == 'y' ] && Uninstall_openssl + fi +fi diff --git a/bin/upgrade.sh b/bin/upgrade.sh new file mode 100644 index 0000000..645d071 --- /dev/null +++ b/bin/upgrade.sh @@ -0,0 +1,162 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# Upgrade Software versions for OneinStack # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/versions.txt +. ./config/options.conf +. ./lib/color.sh +. ./lib/check_os.sh +. ./lib/check_dir.sh +. ./lib/download.sh +. ./lib/get_char.sh +. ./modules/upgrade/upgrade_web.sh +. ./modules/upgrade/upgrade_db.sh +. ./modules/upgrade/upgrade_php.sh +. ./modules/upgrade/upgrade_redis.sh +. ./modules/upgrade/upgrade_phpmyadmin.sh +. ./modules/upgrade/upgrade_oneinstack.sh + +# Ensure a `python` interpreter exists for the legacy *.py helpers +# (Ubuntu 22.04+ ships only `python3`). Without this, get_public_ipaddr.py / +# get_ipaddr_state.py silently fail and mirror selection falls back to upstream. +if [ ! -e "/usr/bin/python" ] && command -v python3 >/dev/null 2>&1; then + ln -s "$(command -v python3)" /usr/bin/python +fi + +# get the IP information +PUBLIC_IPADDR=$(./lib/py/get_public_ipaddr.py) +IPADDR_COUNTRY=$(./lib/py/get_ipaddr_state.py ${PUBLIC_IPADDR}) + +Show_Help() { + echo + echo "Usage: $0 command ...[version].... + --help, -h Show this help message + --nginx [version] Upgrade Nginx + --db [version] Upgrade MySQL/MariaDB + --php [version] Upgrade PHP + --redis [version] Upgrade Redis + --phpmyadmin [version] Upgrade phpMyAdmin + --oneinstack Upgrade OneinStack latest + --acme.sh Upgrade acme.sh latest + " +} + +ARG_NUM=$# +TEMP=`getopt -o h --long help,nginx:,db:,php:,redis:,phpmyadmin:,oneinstack,acme.sh -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + --nginx) + nginx_flag=y; NEW_nginx_ver=$2; shift 2 + ;; + --db) + db_flag=y; NEW_db_ver=$2; shift 2 + ;; + --php) + php_flag=y; NEW_php_ver=$2; shift 2 + ;; + --redis) + redis_flag=y; NEW_redis_ver=$2; shift 2 + ;; + --phpmyadmin) + phpmyadmin_flag=y; NEW_phpmyadmin_ver=$2; shift 2 + ;; + --oneinstack) + NEW_oneinstack_ver=latest; shift 1 + ;; + --acme.sh) + NEW_acme_ver=latest; shift 1 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +Menu() { + while :; do + printf " +What Are You Doing? +\t${CMSG} 1${CEND}. Upgrade Nginx +\t${CMSG} 2${CEND}. Upgrade MySQL/MariaDB +\t${CMSG} 3${CEND}. Upgrade PHP +\t${CMSG} 4${CEND}. Upgrade Redis +\t${CMSG} 5${CEND}. Upgrade phpMyAdmin +\t${CMSG} 6${CEND}. Upgrade OneinStack latest +\t${CMSG} 7${CEND}. Upgrade acme.sh latest +\t${CMSG} q${CEND}. Exit +" + echo + read -e -p "Please input the correct option: " Upgrade_flag + if [[ ! "${Upgrade_flag}" =~ ^[1-7,q]$ ]]; then + echo "${CWARNING}input error! Please only input 1~7 and q${CEND}" + else + case "${Upgrade_flag}" in + 1) + [ -e "${nginx_install_dir}/sbin/nginx" ] && Upgrade_Nginx + ;; + 2) + Upgrade_DB + ;; + 3) + Upgrade_PHP + ;; + 4) + Upgrade_Redis + ;; + 5) + Upgrade_phpMyAdmin + ;; + 6) + Upgrade_OneinStack + ;; + 7) + [ -e ~/.acme.sh/acme.sh ] && { ~/.acme.sh/acme.sh --force --upgrade; ~/.acme.sh/acme.sh --version; } + ;; + q) + exit + ;; + esac + fi + done +} + +if [ ${ARG_NUM} == 0 ]; then + Menu +else + [ "${nginx_flag}" == 'y' ] && Upgrade_Nginx + [ "${db_flag}" == 'y' ] && Upgrade_DB + [ "${php_flag}" == 'y' ] && Upgrade_PHP + [ "${redis_flag}" == 'y' ] && Upgrade_Redis + [ "${phpmyadmin_flag}" == 'y' ] && Upgrade_phpMyAdmin + [ "${NEW_oneinstack_ver}" == 'latest' ] && Upgrade_OneinStack + [ "${NEW_acme_ver}" == 'latest' ] && [ -e ~/.acme.sh/acme.sh ] && { ~/.acme.sh/acme.sh --force --upgrade; ~/.acme.sh/acme.sh --version; } +fi diff --git a/bin/vhost.sh b/bin/vhost.sh new file mode 100644 index 0000000..ee40398 --- /dev/null +++ b/bin/vhost.sh @@ -0,0 +1,780 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +clear +printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != '0' ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +oneinstack_dir="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")/.." && pwd)" +cd "${oneinstack_dir}" || exit 1 +. ./config/options.conf +. ./lib/color.sh +. ./lib/check_dir.sh +. ./lib/check_os.sh +. ./lib/get_char.sh + +Show_Help() { + echo + echo "Usage: $0 command ...[parameters].... + --help, -h Show this help message + --quiet, -q quiet operation + --list, -l List Virtualhost + --mphp_ver [74/80/81] Use another PHP version (PATH: /usr/local/php${mphp_ver}) + --proxy Use proxy + --add Add Virtualhost + --delete, --del Delete Virtualhost + --httponly Use HTTP Only + --selfsigned Use your own SSL Certificate and Key + --letsencrypt Use Let's Encrypt to Create SSL Certificate and Key + --dnsapi Use dns API to automatically issue Let's Encrypt Cert + " +} + +ARG_NUM=$# +TEMP=`getopt -o hql --long help,quiet,list,proxy,mphp_ver:,add,delete,del,httponly,selfsigned,letsencrypt,dnsapi -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + -q|--quiet) + quiet_flag=y; shift 1 + ;; + -l|--list) + list_flag=y; shift 1 + ;; + --mphp_ver) + mphp_ver=$2; mphp_flag=y; shift 2 + [[ ! "${mphp_ver}" =~ ^(74|80|81)$ ]] && { echo "${CWARNING}mphp_ver input error! Please only input number 74/80/81${CEND}"; unset mphp_ver mphp_flag; } + ;; + --proxy) + proxy_flag=y; shift 1 + ;; + --add) + add_flag=y; shift 1 + ;; + --delete|--del) + delete_flag=y; shift 1 + ;; + --httponly) + sslquiet_flag=y + httponly_flag=y + Domian_Mode=1 + shift 1 + ;; + --selfsigned) + sslquiet_flag=y + selfsigned_flag=y + Domian_Mode=2 + shift 1 + ;; + --letsencrypt) + sslquiet_flag=y + letsencrypt_flag=y + Domian_Mode=3 + shift 1 + ;; + --dnsapi) + sslquiet_flag=y + dnsapi_flag=y + letsencrypt_flag=y + shift 1 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + +Choose_ENV() { + # Only Nginx is supported; PHP-FPM is the backend for PHP applications. + NGX_FLAG=php +} + +Create_SSL() { + if [ "${Domian_Mode}" == '2' ]; then + printf " +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +" + echo + read -e -p "Country Name (2 letter code) [CN]: " SELFSIGNEDSSL_C + SELFSIGNEDSSL_C=${SELFSIGNEDSSL_C:-CN} + # shellcheck disable=SC2104 + [ ${#SELFSIGNEDSSL_C} != 2 ] && { echo "${CWARNING}input error, You must input 2 letter code country name${CEND}"; continue; } + echo + read -e -p "State or Province Name (full name) [Shanghai]: " SELFSIGNEDSSL_ST + SELFSIGNEDSSL_ST=${SELFSIGNEDSSL_ST:-Shanghai} + echo + read -e -p "Locality Name (eg, city) [Shanghai]: " SELFSIGNEDSSL_L + SELFSIGNEDSSL_L=${SELFSIGNEDSSL_L:-Shanghai} + echo + read -e -p "Organization Name (eg, company) [Example Inc.]: " SELFSIGNEDSSL_O + SELFSIGNEDSSL_O=${SELFSIGNEDSSL_O:-"Example Inc."} + echo + read -e -p "Organizational Unit Name (eg, section) [IT Dept.]: " SELFSIGNEDSSL_OU + SELFSIGNEDSSL_OU=${SELFSIGNEDSSL_OU:-"IT Dept."} + + openssl req -utf8 -new -newkey rsa:2048 -sha256 -nodes -out ${PATH_SSL}/${domain}.csr -keyout ${PATH_SSL}/${domain}.key -subj "/C=${SELFSIGNEDSSL_C}/ST=${SELFSIGNEDSSL_ST}/L=${SELFSIGNEDSSL_L}/O=${SELFSIGNEDSSL_O}/OU=${SELFSIGNEDSSL_OU}/CN=${domain}" > /dev/null 2>&1 + openssl x509 -req -days 36500 -sha256 -in ${PATH_SSL}/${domain}.csr -signkey ${PATH_SSL}/${domain}.key -out ${PATH_SSL}/${domain}.crt > /dev/null 2>&1 + elif [ "${Domian_Mode}" == '3' -o "${dnsapi_flag}" == 'y' ]; then + while :; do echo + echo 'Please select domain cert key length.' + echo "${CMSG}Enter one of 2048, 3072, 4096, 8192 will issue a RSA cert.${CEND}" + echo "${CMSG}Enter one of ec-256, ec-384, ec-521 will issue a ECC cert.${CEND}" + echo + read -e -p "Please enter your cert key length (default 2048): " CERT_KEYLENGTH + if [ "${CERT_KEYLENGTH}" == "" ]; then + CERT_KEYLENGTH="2048" + break + elif [[ "${CERT_KEYLENGTH}" =~ ^2048$|^3072$|^4096$|^8192$|^ec-256$|^ec-384$|^ec-521$ ]]; then + break + else + echo "${CWARNING}input error!${CEND}" + fi + done + if [ ! -e ~/.acme.sh/ca/acme.zerossl.com/account.key ]; then + while :; do echo + read -e -p "Please enter your email: " EMAIL + echo + if [[ "${EMAIL}" =~ ^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+\.[A-Za-z]{2,9}$ ]]; then + break + else + echo "${CWARNING}input error!${CEND}" + fi + done + ~/.acme.sh/acme.sh --register-account -m ${EMAIL} + fi + if [ "${moredomain}" == "*.${domain}" -o "${dnsapi_flag}" == 'y' ]; then + while :; do echo + echo 'Please select DNS provider:' + echo "${CMSG}dp${CEND},${CMSG}cx${CEND},${CMSG}ali${CEND},${CMSG}cf${CEND},${CMSG}aws${CEND},${CMSG}linode${CEND},${CMSG}he${CEND},${CMSG}namesilo${CEND},${CMSG}dgon${CEND},${CMSG}freedns${CEND},${CMSG}gd${CEND},${CMSG}namecom${CEND} and so on." + echo "${CMSG}More: https://oneinstack.com/faq/letsencrypt${CEND}" + read -e -p "Please enter your DNS provider: " DNS_PRO + if [ -e ~/.acme.sh/dnsapi/dns_${DNS_PRO}.sh ]; then + break + else + echo "${CWARNING}You DNS api mode is not supported${CEND}" + fi + done + while :; do echo + echo "Syntax: export Key1=Value1 ; export Key2=Value1" + read -e -p "Please enter your dnsapi parameters: " DNS_PAR + echo + eval ${DNS_PAR} + if [ $? == 0 ]; then + break + else + echo "${CWARNING}Syntax error! PS: export Ali_Key=LTq ; export Ali_Secret=0q5E${CEND}" + fi + done + [ "${moredomainame_flag}" == 'y' ] && moredomainame_D="$(for D in ${moredomainame}; do echo -d ${D}; done)" + ~/.acme.sh/acme.sh --force --issue -k ${CERT_KEYLENGTH} --dns dns_${DNS_PRO} -d ${domain} ${moredomainame_D} + else + if [ "${nginx_ssl_flag}" == 'y' ]; then + [ ! -d ${web_install_dir}/conf/vhost ] && mkdir ${web_install_dir}/conf/vhost + if [ -n "`ifconfig | grep inet6`" ]; then + echo "server { listen 80; listen [::]:80; server_name ${domain}${moredomainame}; root ${vhostdir}; access_log off; }" > ${web_install_dir}/conf/vhost/${domain}.conf + else + echo "server { listen 80; server_name ${domain}${moredomainame}; root ${vhostdir}; access_log off; }" > ${web_install_dir}/conf/vhost/${domain}.conf + fi + ${web_install_dir}/sbin/nginx -s reload + fi + + auth_file="`< /dev/urandom tr -dc A-Za-z0-9 | head -c8`".html + auth_str='oneinstack'; echo ${auth_str} > ${vhostdir}/${auth_file} + for D in ${domain} ${moredomainame} + do + curl_str=`curl --connect-timeout 30 -4 -s $D/${auth_file} 2>&1` + [ "${curl_str}" != "${auth_str}" ] && { echo; echo "${CFAILURE}Let's Encrypt Verify error! DNS problem: NXDOMAIN looking up A for ${D}${CEND}"; } + done + rm -f ${vhostdir}/${auth_file} + [ "${moredomainame_flag}" == 'y' ] && moredomainame_D="$(for D in ${moredomainame}; do echo -d ${D}; done)" + ~/.acme.sh/acme.sh --force --issue -k ${CERT_KEYLENGTH} -w ${vhostdir} -d ${domain} ${moredomainame_D} + fi + [ -e "${PATH_SSL}/${domain}.crt" ] && rm -f ${PATH_SSL}/${domain}.{crt,key} + Nginx_cmd="/bin/systemctl restart nginx" + Command="${Nginx_cmd}" + if [ -s ~/.acme.sh/${domain}/fullchain.cer ] && [[ "${CERT_KEYLENGTH}" =~ ^2048$|^3072$|^4096$|^8192$ ]]; then + ~/.acme.sh/acme.sh --force --install-cert -d ${domain} --fullchain-file ${PATH_SSL}/${domain}.crt --key-file ${PATH_SSL}/${domain}.key --reloadcmd "${Command}" > /dev/null + elif [ -s ~/.acme.sh/${domain}_ecc/fullchain.cer ] && [[ "${CERT_KEYLENGTH}" =~ ^ec-256$|^ec-384$|^ec-521$ ]]; then + ~/.acme.sh/acme.sh --force --install-cert --ecc -d ${domain} --fullchain-file ${PATH_SSL}/${domain}.crt --key-file ${PATH_SSL}/${domain}.key --reloadcmd "${Command}" > /dev/null + else + echo "${CFAILURE}Error: Create Let's Encrypt SSL Certificate failed! ${CEND}" + [ -e "${web_install_dir}/conf/vhost/${domain}.conf" ] && rm -f ${web_install_dir}/conf/vhost/${domain}.conf + exit 1 + fi + fi +} + +Print_SSL() { + if [ "${Domian_Mode}" == '2' ]; then + echo "$(printf "%-30s" "Self-signed SSL Certificate:")${CMSG}${PATH_SSL}/${domain}.crt${CEND}" + echo "$(printf "%-30s" "SSL Private Key:")${CMSG}${PATH_SSL}/${domain}.key${CEND}" + echo "$(printf "%-30s" "SSL CSR File:")${CMSG}${PATH_SSL}/${domain}.csr${CEND}" + elif [ "${Domian_Mode}" == '3' -o "${dnsapi_flag}" == 'y' ]; then + echo "$(printf "%-30s" "Let's Encrypt SSL Certificate:")${CMSG}${PATH_SSL}/${domain}.crt${CEND}" + echo "$(printf "%-30s" "SSL Private Key:")${CMSG}${PATH_SSL}/${domain}.key${CEND}" + fi +} + +Input_Add_proxy() { + while :; do echo + read -e -p "Please input the correct proxy_pass: " Proxy_Pass + if [ -z "$(echo $Proxy_Pass | grep -E '^http://|https://')" ]; then + echo "${CFAILURE}input error! Please only input example http://192.168.1.1:8080${CEND}" + else + echo "proxy_pass=${Proxy_Pass}" + break + fi + done +} + +Input_Add_domain() { + if [ "${sslquiet_flag}" != 'y' ]; then + while :;do + printf " +What Are You Doing? +\t${CMSG}1${CEND}. Use HTTP Only +\t${CMSG}2${CEND}. Use your own SSL Certificate and Key +\t${CMSG}3${CEND}. Use Let's Encrypt to Create SSL Certificate and Key +\t${CMSG}q${CEND}. Exit +" + read -e -p "Please input the correct option: " Domian_Mode + if [[ ! "${Domian_Mode}" =~ ^[1-3,q]$ ]]; then + echo "${CFAILURE}input error! Please only input 1~3 and q${CEND}" + else + break + fi + done + fi + + #Multiple_PHP + if [ $(ls /dev/shm/php*-cgi.sock 2> /dev/null | wc -l) -ge 2 ]; then + if [ "${mphp_flag}" != 'y' ]; then + PHP_detail_ver=`${php_install_dir}/bin/php-config --version` + PHP_main_ver=${PHP_detail_ver%.*} + while :; do echo + echo 'Please select a version of the PHP:' + echo -e "\t${CMSG} 0${CEND}. PHP ${PHP_main_ver} (default)" + [ -e "/dev/shm/php74-cgi.sock" ] && echo -e "\t${CMSG} 1${CEND}. PHP 7.4" + [ -e "/dev/shm/php80-cgi.sock" ] && echo -e "\t${CMSG} 2${CEND}. PHP 8.0" + [ -e "/dev/shm/php81-cgi.sock" ] && echo -e "\t${CMSG} 3${CEND}. PHP 8.1" + read -e -p "Please input a number:(Default 0 press Enter) " php_option + php_option=${php_option:-0} + if [[ ! ${php_option} =~ ^[0-3]$ ]]; then + echo "${CWARNING}input error! Please only input number 0~3${CEND}" + else + break + fi + done + fi + [ "${php_option}" == '1' ] && mphp_ver=74 + [ "${php_option}" == '2' ] && mphp_ver=80 + [ "${php_option}" == '3' ] && mphp_ver=81 + [ ! -e "/dev/shm/php${mphp_ver}-cgi.sock" ] && unset mphp_ver + fi + + case "${NGX_FLAG}" in + "php") + NGX_CONF=$(echo -e "location ~ [^/]\.php(/|$) {\n #fastcgi_pass remote_php_ip:9000;\n fastcgi_pass unix:/dev/shm/php${mphp_ver}-cgi.sock;\n fastcgi_index index.php;\n include fastcgi.conf;\n }") + ;; + esac + + if [ "${Domian_Mode}" == '3' -o "${dnsapi_flag}" == 'y' ] && [ ! -e ~/.acme.sh/acme.sh ]; then + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e acme.sh-master.tar.gz ] && wget -qc http://mirrors.linuxeye.com/oneinstack/src/acme.sh-master.tar.gz + tar xzf acme.sh-master.tar.gz + pushd acme.sh-master > /dev/null + ./acme.sh --install > /dev/null 2>&1 + popd > /dev/null + popd > /dev/null + fi + [ -e ~/.acme.sh/account.conf ] && sed -i '/^CERT_HOME=/d' ~/.acme.sh/account.conf + if [[ "${Domian_Mode}" =~ ^[2-3]$ ]] || [ "${dnsapi_flag}" == 'y' ]; then + if [ -e "${web_install_dir}/sbin/nginx" ]; then + nginx_ssl_flag=y + PATH_SSL=${web_install_dir}/conf/ssl + [ ! -d "${PATH_SSL}" ] && mkdir ${PATH_SSL} + else + nginx_ssl_flag=y + PATH_SSL=${web_install_dir}/conf/ssl + [ ! -d "${PATH_SSL}" ] && mkdir ${PATH_SSL} + fi + elif [ "${Domian_Mode}" == 'q' ]; then + exit 1 + fi + + while :; do echo + read -e -p "Please input domain(example: www.example.com): " domain + if [ -z "$(echo ${domain} | grep '.*\..*')" ]; then + echo "${CWARNING}Your ${domain} is invalid! ${CEND}" + else + break + fi + done + + if [ -e "${web_install_dir}/conf/vhost/${domain}.conf" ]; then + [ -e "${web_install_dir}/conf/vhost/${domain}.conf" ] && echo -e "${domain} in the Nginx already exist! \nYou can delete ${CMSG}${web_install_dir}/conf/vhost/${domain}.conf${CEND} and re-create" + exit + else + echo "domain=${domain}" + fi + if [[ -z ${proxy_flag} || "${proxy_flag}" != 'y' ]]; then + while :; do echo + echo "Please input the directory for the domain:${domain} :" + read -e -p "(Default directory: ${wwwroot_dir}/${domain}): " vhostdir + if [ -n "${vhostdir}" -a -z "$(echo ${vhostdir} | grep '^/')" ]; then + echo "${CWARNING}input error! Press Enter to continue...${CEND}" + else + if [ -z "${vhostdir}" ]; then + vhostdir="${wwwroot_dir}/${domain}" + echo "Virtual Host Directory=${CMSG}${vhostdir}${CEND}" + fi + echo + echo "Create Virtul Host directory......" + mkdir -p ${vhostdir} + echo "set permissions of Virtual Host directory......" + chown -R ${run_user}:${run_group} ${vhostdir} + break + fi + done + fi + + while :; do echo + read -e -p "Do you want to add more domain name? [y/n]: " moredomainame_flag + if [[ ! ${moredomainame_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + + if [ "${moredomainame_flag}" == 'y' ]; then + while :; do echo + read -e -p "Type domainname or IP(example: example.com other.example.com): " moredomain + if [ -z "$(echo ${moredomain} | grep '.*\..*')" ]; then + echo "${CWARNING}Your ${domain} is invalid! ${CEND}" + else + [ "${moredomain}" == "${domain}" ] && echo "${CWARNING}Domain name already exists! ${CND}" && continue + echo domain list="$moredomain" + moredomainame=" $moredomain" + break + fi + done + + if [ -e "${web_install_dir}/sbin/nginx" ]; then + while :; do echo + read -e -p "Do you want to redirect from ${moredomain} to ${domain}? [y/n]: " redirect_flag + if [[ ! ${redirect_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + [ "${redirect_flag}" == 'y' ] && Nginx_redirect="if (\$host != ${domain}) { return 301 \$scheme://${domain}\$request_uri; }" + fi + fi + + if [ "${nginx_ssl_flag}" == 'y' ]; then + while :; do echo + read -e -p "Do you want to redirect all HTTP requests to HTTPS? [y/n]: " https_flag + if [[ ! ${https_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + + if [[ "$(${web_install_dir}/sbin/nginx -V 2>&1 | grep -Eo 'with-http_v2_module')" = 'with-http_v2_module' ]]; then + LISTENOPT="443 ssl http2" + else + LISTENOPT="443 ssl spdy" + fi + Create_SSL + if [ -n "`ifconfig | grep inet6`" ]; then + Nginx_conf=$(echo -e "listen 80;\n listen [::]:80;\n listen ${LISTENOPT};\n listen [::]:${LISTENOPT};\n ssl_certificate ${PATH_SSL}/${domain}.crt;\n ssl_certificate_key ${PATH_SSL}/${domain}.key;\n ssl_protocols TLSv1.2 TLSv1.3;\n ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;\n ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;\n ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;\n ssl_conf_command Options PrioritizeChaCha;\n ssl_prefer_server_ciphers on;\n ssl_session_timeout 10m;\n ssl_session_cache shared:SSL:10m;\n ssl_buffer_size 2k;\n add_header Strict-Transport-Security max-age=15768000;\n ssl_stapling on;\n ssl_stapling_verify on;\n") + else + Nginx_conf=$(echo -e "listen 80;\n listen ${LISTENOPT};\n ssl_certificate ${PATH_SSL}/${domain}.crt;\n ssl_certificate_key ${PATH_SSL}/${domain}.key;\n ssl_protocols TLSv1.2 TLSv1.3;\n ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;\n ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;\n ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;\n ssl_conf_command Options PrioritizeChaCha;\n ssl_prefer_server_ciphers on;\n ssl_session_timeout 10m;\n ssl_session_cache shared:SSL:10m;\n ssl_buffer_size 2k;\n add_header Strict-Transport-Security max-age=15768000;\n ssl_stapling on;\n ssl_stapling_verify on;\n") + fi + else + if [ -n "`ifconfig | grep inet6`" ]; then + Nginx_conf=$(echo -e "listen 80;\n listen [::]:80;") + else + Nginx_conf=$(echo -e "listen 80;") + fi + fi +} + +Nginx_anti_hotlinking() { + while :; do echo + read -e -p "Do you want to add hotlink protection? [y/n]: " anti_hotlinking_flag + if [[ ! ${anti_hotlinking_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + + if [ -n "$(echo ${domain} | grep '.*\..*\..*')" ]; then + domain_allow="*.${domain#*.} ${domain}" + else + domain_allow="*.${domain} ${domain}" + fi + + if [ "${anti_hotlinking_flag}" == 'y' ]; then + if [ "${moredomainame_flag}" == 'y' -a "${moredomain}" != "*.${domain}" ]; then + domain_allow_all=${domain_allow}${moredomainame} + else + domain_allow_all=${domain_allow} + fi + domain_allow_all=`echo ${domain_allow_all} | tr ' ' '\n' | awk '!a[$1]++' | xargs` + anti_hotlinking=$(echo -e "location ~ .*\.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv|mp4)$ {\n valid_referers none blocked ${domain_allow_all};\n if (\$invalid_referer) {\n return 403;\n }\n }") + fi +} + +Nginx_rewrite() { + [ ! -d "${web_install_dir}/conf/rewrite" ] && mkdir ${web_install_dir}/conf/rewrite + while :; do echo + read -e -p "Allow Rewrite rule? [y/n]: " rewrite_flag + if [[ ! "${rewrite_flag}" =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + if [ "${rewrite_flag}" == 'n' ]; then + rewrite="none" + touch "${web_install_dir}/conf/rewrite/${rewrite}.conf" + else + echo + echo "Please input the rewrite of programme :" + echo "${CMSG}wordpress${CEND},${CMSG}opencart${CEND},${CMSG}magento2${CEND},${CMSG}drupal${CEND},${CMSG}joomla${CEND},${CMSG}codeigniter${CEND},${CMSG}laravel${CEND}" + echo "${CMSG}thinkphp${CEND},${CMSG}pathinfo${CEND},${CMSG}discuz${CEND},${CMSG}typecho${CEND},${CMSG}ecshop${CEND},${CMSG}nextcloud${CEND},${CMSG}zblog${CEND},${CMSG}whmcs${CEND} rewrite was exist." + read -e -p "(Default rewrite: other): " rewrite + if [ "${rewrite}" == "" ]; then + rewrite="other" + fi + echo "You choose rewrite=${CMSG}$rewrite${CEND}" + [ "${NGX_FLAG}" == 'php' -a "${rewrite}" == "joomla" ] && NGX_CONF=$(echo -e "location ~ \\.php\$ {\n #fastcgi_pass remote_php_ip:9000;\n fastcgi_pass unix:/dev/shm/php${mphp_ver}-cgi.sock;\n fastcgi_index index.php;\n include fastcgi.conf;\n }") + [ "${NGX_FLAG}" == 'php' ] && [[ "${rewrite}" =~ ^codeigniter$|^thinkphp$|^pathinfo$ ]] && NGX_CONF=$(echo -e "location ~ [^/]\.php(/|\$) {\n #fastcgi_pass remote_php_ip:9000;\n fastcgi_pass unix:/dev/shm/php${mphp_ver}-cgi.sock;\n fastcgi_index index.php;\n include fastcgi.conf;\n fastcgi_split_path_info ^(.+?\.php)(/.*)\$;\n set \$path_info \$fastcgi_path_info;\n fastcgi_param PATH_INFO \$path_info;\n try_files \$fastcgi_script_name =404; \n }") + [ "${NGX_FLAG}" == 'php' -a "${rewrite}" == "typecho" ] && NGX_CONF=$(echo -e "location ~ .*\.php(\/.*)*\$ {\n #fastcgi_pass remote_php_ip:9000;\n fastcgi_pass unix:/dev/shm/php${mphp_ver}-cgi.sock;\n fastcgi_index index.php;\n include fastcgi.conf;\n set \$path_info \"\";\n set \$real_script_name \$fastcgi_script_name;\n if (\$fastcgi_script_name ~ \"^(.+?\.php)(/.+)\$\") {\n set \$real_script_name \$1;\n set \$path_info \$2;\n }\n fastcgi_param SCRIPT_FILENAME \$document_root\$real_script_name;\n fastcgi_param SCRIPT_NAME \$real_script_name;\n fastcgi_param PATH_INFO \$path_info;\n }") + if [[ ! "${rewrite}" =~ ^magento2$|^pathinfo$ ]]; then + if [ -e "config/${rewrite}.conf" ]; then + /bin/cp config/${rewrite}.conf ${web_install_dir}/conf/rewrite/${rewrite}.conf + else + touch "${web_install_dir}/conf/rewrite/${rewrite}.conf" + fi + fi + fi +} + +Nginx_log() { + while :; do echo + read -e -p "Allow Nginx access_log? [y/n]: " access_flag + if [[ ! "${access_flag}" =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + if [ "${access_flag}" == 'n' ]; then + Nginx_log="access_log off;" + else + Nginx_log="access_log ${wwwlogs_dir}/${domain}_nginx.log combined;" + echo "You access log file=${CMSG}${wwwlogs_dir}/${domain}_nginx.log${CEND}" + fi +} + + + +Create_nginx_phpfpm_conf() { + [ ! -d ${web_install_dir}/conf/vhost ] && mkdir ${web_install_dir}/conf/vhost + cat > ${web_install_dir}/conf/vhost/${domain}.conf << EOF +server { + ${Nginx_conf} + server_name ${domain}${moredomainame}; + ${Nginx_log} + index index.html index.htm index.php; + root ${vhostdir}; + ${Nginx_redirect} + include ${web_install_dir}/conf/rewrite/${rewrite}.conf; + #error_page 404 /404.html; + #error_page 502 /502.html; + ${anti_hotlinking} + ${NGX_CONF} + + location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ { + expires 30d; + access_log off; + } + location ~ .*\.(js|css)?$ { + expires 7d; + access_log off; + } + location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) { + deny all; + } + location /.well-known { + allow all; + } +} +EOF + + [ "${rewrite}" == 'pathinfo' ] && sed -i '/pathinfo.conf;$/d' ${web_install_dir}/conf/vhost/${domain}.conf + if [ "${rewrite}" == 'magento2' -a -e "config/${rewrite}.conf" ]; then + /bin/cp config/${rewrite}.conf ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@/dev/shm/php-cgi.sock@/dev/shm/php${mphp_ver}-cgi.sock@g" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ set \$MAGE_ROOT.*;@ set \$MAGE_ROOT ${vhostdir};@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@ server_name ${domain}${moredomainame};@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ${Nginx_log}@" ${web_install_dir}/conf/vhost/${domain}.conf + if [ "${anti_hotlinking_flag}" == 'y' ]; then + sed -i "s@^ root.*;@&\n }@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n }@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n return 403;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n rewrite ^/ http://www.linuxeye.com/403.html;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n if (\$invalid_referer) {@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n valid_referers none blocked ${domain_allow_all};@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n location ~ .*\.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv|mp4)\$ {@" ${web_install_dir}/conf/vhost/${domain}.conf + fi + + [ "${redirect_flag}" == 'y' ] && sed -i "s@^ root.*;@&\n if (\$host != ${domain}) { return 301 \$scheme://${domain}\$request_uri; }@" ${web_install_dir}/conf/vhost/${domain}.conf + + if [ "${nginx_ssl_flag}" == 'y' ]; then + sed -i "s@^ listen 80;@&\n listen ${LISTENOPT};@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_stapling_verify on;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_stapling on;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n add_header Strict-Transport-Security max-age=15768000;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_buffer_size 2k;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_session_cache shared:SSL:10m;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_session_timeout 10m;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_prefer_server_ciphers on;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_conf_command Options PrioritizeChaCha;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_protocols TLSv1.2 TLSv1.3;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_certificate_key ${PATH_SSL}/${domain}.key;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ server_name.*;@&\n ssl_certificate ${PATH_SSL}/${domain}.crt;@" ${web_install_dir}/conf/vhost/${domain}.conf + fi + fi + + [ "${https_flag}" == 'y' ] && sed -i "s@^ root.*;@&\n if (\$ssl_protocol = \"\") { return 301 https://\$host\$request_uri; }@" ${web_install_dir}/conf/vhost/${domain}.conf + + echo + ${web_install_dir}/sbin/nginx -t + if [ $? == 0 ]; then + echo "Reload Nginx......" + ${web_install_dir}/sbin/nginx -s reload + else + rm -f ${web_install_dir}/conf/vhost/${domain}.conf + echo "Create virtualhost ... [${CFAILURE}FAILED${CEND}]" + exit 1 + fi + + printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# For more information please visit https://oneinstack.com # +####################################################################### +" + echo "$(printf "%-30s" "Your domain:")${CMSG}${domain}${CEND}" + echo "$(printf "%-30s" "Virtualhost conf:")${CMSG}${web_install_dir}/conf/vhost/${domain}.conf${CEND}" + echo "$(printf "%-30s" "Directory of:")${CMSG}${vhostdir}${CEND}" + [ "${rewrite_flag}" == 'y' -a "${rewrite}" != 'magento2' -a "${rewrite}" != 'pathinfo' ] && echo "$(printf "%-30s" "Rewrite rule:")${CMSG}${web_install_dir}/conf/rewrite/${rewrite}.conf${CEND}" + Print_SSL +} + +Create_nginx_proxy_conf() { + [ ! -d ${web_install_dir}/conf/vhost ] && mkdir ${web_install_dir}/conf/vhost + cat > ${web_install_dir}/conf/vhost/${domain}.conf << EOF +server { + ${Nginx_conf} + server_name ${domain}${moredomainame}; + ${Nginx_log} + index index.html index.htm index.php; + ${Nginx_redirect} + location / { + proxy_pass ${Proxy_Pass}; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header Host \$http_host; + proxy_set_header X-NginX-Proxy true; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_max_temp_file_size 0; + } + + #error_page 404 /404.html; + #error_page 502 /502.html; + ${anti_hotlinking} + + location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ { + expires 30d; + access_log off; + } + location ~ .*\.(js|css)?$ { + expires 7d; + access_log off; + } + location ~ /(\.user\.ini|\.ht|\.git|\.svn|\.project|LICENSE|README\.md) { + deny all; + } + location /.well-known { + allow all; + } +} +EOF + + [ "${redirect_flag}" == 'y' ] && sed -i "s@^ root.*;@&\n if (\$host != ${domain}) { return 301 \$scheme://${domain}\$request_uri; }@" ${web_install_dir}/conf/vhost/${domain}.conf + + if [ "${anti_hotlinking_flag}" == 'y' ]; then + sed -i "s@^ root.*;@&\n }@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n }@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n return 403;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n rewrite ^/ http://www.linuxeye.com/403.html;@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n if (\$invalid_referer) {@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n valid_referers none blocked ${domain_allow_all};@" ${web_install_dir}/conf/vhost/${domain}.conf + sed -i "s@^ root.*;@&\n location ~ .*\.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv|mp4)\$ {@" ${web_install_dir}/conf/vhost/${domain}.conf + fi + + [ "${https_flag}" == 'y' ] && sed -i "s@^ root.*;@&\n if (\$ssl_protocol = \"\") { return 301 https://\$host\$request_uri; }@" ${web_install_dir}/conf/vhost/${domain}.conf + + echo + ${web_install_dir}/sbin/nginx -t + if [ $? == 0 ]; then + echo "Reload Nginx......" + ${web_install_dir}/sbin/nginx -s reload + else + rm -f ${web_install_dir}/conf/vhost/${domain}.conf + echo "Create virtualhost ... [${CFAILURE}FAILED${CEND}]" + exit 1 + fi + + printf " +####################################################################### +# OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ # +# For more information please visit https://oneinstack.com # +####################################################################### +" + echo "$(printf "%-30s" "Your domain:")${CMSG}${domain}${CEND}" + echo "$(printf "%-30s" "Virtualhost conf:")${CMSG}${web_install_dir}/conf/vhost/${domain}.conf${CEND}" + #echo "$(printf "%-30s" "Directory of:")${CMSG}${vhostdir}${CEND}" + [ "${rewrite_flag}" == 'y' -a "${rewrite}" != 'magento2' -a "${rewrite}" != 'pathinfo' ] && echo "$(printf "%-30s" "Rewrite rule:")${CMSG}${web_install_dir}/conf/rewrite/${rewrite}.conf${CEND}" + Print_SSL +} + + +Add_Vhost() { + if [ -e "${web_install_dir}/sbin/nginx" ]; then + Choose_ENV + Input_Add_domain + Nginx_anti_hotlinking + if [ "${proxy_flag}" == "y" ]; then + Input_Add_proxy + Create_nginx_proxy_conf + else + Nginx_rewrite + Nginx_log + Create_nginx_phpfpm_conf + fi + else + echo "Error! ${CFAILURE}Nginx${CEND} not found!" + fi +} + +Del_NGX_Vhost() { + if [ -e "${web_install_dir}/sbin/nginx" ]; then + [ -d "${web_install_dir}/conf/vhost" ] && Domain_List=$(ls ${web_install_dir}/conf/vhost | sed "s@.conf@@g") + if [ -n "${Domain_List}" ]; then + echo + echo "Virtualhost list:" + echo ${CMSG}${Domain_List}${CEND} + while :; do echo + read -e -p "Please input a domain you want to delete: " domain + if [ -z "$(echo ${domain} | grep '.*\..*')" ]; then + echo "${CWARNING}Your ${domain} is invalid! ${CEND}" + else + if [ -e "${web_install_dir}/conf/vhost/${domain}.conf" ]; then + Directory=$(grep '^ root' ${web_install_dir}/conf/vhost/${domain}.conf | head -1 | awk -F'[ ;]' '{print $(NF-1)}') + rm -f ${web_install_dir}/conf/vhost/${domain}.conf + [ -e "${web_install_dir}/conf/ssl/${domain}.crt" ] && rm -f ${web_install_dir}/conf/ssl/${domain}.{crt,key} + ${web_install_dir}/sbin/nginx -s reload + while :; do echo + read -e -p "Do you want to delete Virtul Host directory? [y/n]: " Del_Vhost_wwwroot_flag + if [[ ! ${Del_Vhost_wwwroot_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + if [ "${Del_Vhost_wwwroot_flag}" == 'y' ]; then + if [ "${quiet_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=$(get_char) + fi + rm -rf ${Directory} + fi + echo + [ -d ~/.acme.sh/${domain} ] && ~/.acme.sh/acme.sh --force --remove -d ${domain} > /dev/null 2>&1 + [ -d ~/.acme.sh/${domain}_ecc ] && ~/.acme.sh/acme.sh --force --remove --ecc -d ${domain} > /dev/null 2>&1 + echo "${CMSG}Domain: ${domain} has been deleted.${CEND}" + echo + else + echo "${CWARNING}Virtualhost: ${domain} was not exist! ${CEND}" + fi + break + fi + done + else + echo "${CWARNING}Virtualhost was not exist! ${CEND}" + fi + fi +} + + + + + +List_Vhost() { + [ -d "${web_install_dir}/conf/vhost" ] && Domain_List=$(ls ${web_install_dir}/conf/vhost | sed "s@.conf@@g") + if [ -n "${Domain_List}" ]; then + echo + echo "Virtualhost list:" + for D in ${Domain_List}; do echo ${CMSG}${D}${CEND}; done + else + echo "${CWARNING}Virtualhost was not exist! ${CEND}" + fi +} + +if [ ${ARG_NUM} == 0 ]; then + Add_Vhost +else + [ "${add_flag}" == 'y' -o "${proxy_flag}" == 'y' -o "${sslquiet_flag}" == 'y' ] && Add_Vhost + [ "${list_flag}" == 'y' ] && List_Vhost + [ "${delete_flag}" == 'y' ] && Del_NGX_Vhost +fi diff --git a/config/options.conf b/config/options.conf new file mode 100644 index 0000000..6a16be6 --- /dev/null +++ b/config/options.conf @@ -0,0 +1,89 @@ +# set the default timezone +timezone=Asia/Shanghai + +# Nginx Apache and PHP-FPM process is run as $run_user(Default "www"), you can freely specify +run_user=www +# Nginx Apache and PHP-FPM process is run as $run_group(Default "www"), you can freely specify +run_group=www + +# set the default install path, you can freely specify +nginx_install_dir=/usr/local/nginx + +mysql_install_dir=/usr/local/mysql +mariadb_install_dir=/usr/local/mariadb +pgsql_install_dir=/usr/local/pgsql +mongo_install_dir=/usr/local/mongodb + +php_install_dir=/usr/local/php + +nodejs_install_dir=/usr/local/node + +pureftpd_install_dir=/usr/local/pureftpd + +redis_install_dir=/usr/local/redis + +python_install_dir=/usr/local/python + +openssl_install_dir=/usr/local/openssl +imagick_install_dir=/usr/local/imagemagick +gmagick_install_dir=/usr/local/graphicsmagick +curl_install_dir=/usr/local/curl +freetype_install_dir=/usr/local/freetype + +# Add modules +nginx_modules_options='' +php_modules_options='' + +######################################################################### +# database data storage directory, you can freely specify +mysql_data_dir=/data/mysql +mariadb_data_dir=/data/mariadb +pgsql_data_dir=/data/pgsql +mongo_data_dir=/data/mongodb + +# web directory, you can customize +wwwroot_dir=/data/wwwroot + +# nginx Generate a log storage directory, you can freely specify. +wwwlogs_dir=/data/wwwlogs + +######################################################################### +# [MySQL/MariaDB] automatically generated, You can't change +dbrootpwd='xlsr$lz2Slrl' + +# [PostgreSQL] automatically generated, You can't change +dbpostgrespwd= + +# [MongoDB] automatically generated, You can't change +dbmongopwd= + +######################################################################### +# Backup Dest directory, change this if you have someother location +backup_dir=/data/backup + +# How many days before the backup directory will be removed +expired_days=5 + +# local,remote,oss,cos,upyun,qiniu,s3,gdrive,dropbox +backup_destination= + +# db ; web, You can't change +backup_content= + +# aliyun OSS Bucket, You can't change +oss_bucket= + +# qiniu Bucket, You can't change +qiniu_bucket= + +# Amazon S3 Bucket, You can't change +s3_bucket= + +# The backup of the database, You can't change +db_name= + +# The backup of the website, You can't change +website_name= + +# oneinstack.tar.gz md5, You can't change +oneinstack_md5= diff --git a/config/versions.txt b/config/versions.txt new file mode 100644 index 0000000..560dde4 --- /dev/null +++ b/config/versions.txt @@ -0,0 +1,97 @@ +# newest software version +# Web +nginx_ver=1.22.1 +openssl11_ver=1.1.1q +openssl_ver=1.0.2u + +pcre_ver=8.45 + +# DB +mysql80_ver=8.0.43 +mysql57_ver=5.7.44 + +mariadb1011_ver=10.11.15 +mariadb118_ver=11.8.5 +mariadb123_ver=12.3.2 + +pgsql1514_ver=15.14 +pgsql1610_ver=16.10 +pgsql176_ver=17.6 +pgsql_ver=15.14 + +mongodb_ver=4.0.26 + +# PHP +php74_ver=7.4.33 +php80_ver=8.0.30 +php81_ver=8.1.27 + +# Nodejs +nodejs_ver=18.12.1 + +libiconv_ver=1.16 +curl_ver=7.86.0 +libmcrypt_ver=2.5.8 +mcrypt_ver=2.6.8 +mhash_ver=0.9.9.9 +freetype_ver=2.10.1 +icu4c_ver=63_1 +libsodium_ver=1.0.18 +libzip_ver=1.2.0 +argon2_ver=20171227 +imagemagick_ver=7.1.0-52 +imagick_ver=3.5.1 +imagick_oldver=3.4.4 +graphicsmagick_ver=1.3.36 +gmagick_ver=2.0.6RC1 +gmagick_oldver=1.1.7RC3 +zendopcache_ver=7.0.5 +apcu_ver=5.1.21 +apcu_oldver=4.0.11 +xcache_ver=3.2.0 +eaccelerator_ver=0.9.6.1 +phalcon_ver=4.1.2 +phalcon_oldver=3.4.5 +yaf_ver=3.3.2 +yar_ver=2.2.0 +swoole_ver=4.8.10 +swoole_oldver=4.5.2 +xdebug_ver=3.1.2 +xdebug_oldver=2.9.8 + +# Ftp +pureftpd_ver=1.0.52 + +# Redis +redis_ver=7.2.3 +redis_oldver=5.0.14 +pecl_redis_ver=5.3.7 +pecl_redis_oldver=4.3.0 + +# MongoDB +pecl_mongodb_ver=1.13.0 +pecl_mongodb_oldver=1.9.2 +pecl_mongo_ver=1.6.16 + +# phpMyadmin +phpmyadmin_ver=5.2.3 +phpmyadmin_oldver=4.4.15.10 + +# jemalloc +jemalloc_ver=5.2.1 + +# boost +boost_ver=1.77.0 +boost_oldver=1.59.0 + +# Others +lua_nginx_module_ver=0.10.22 +luajit2_ver=2.1-20220915 +lua_resty_core_ver=0.1.24 +lua_resty_lrucache_ver=0.13 +lua_cjson_ver=2.1.0.10 +python_ver=3.6.15 +setuptools_ver=61.2.0 +pip_ver=22.0.4 +fail2ban_ver=0.11.2 +fancyindex_ver=0.5.2 diff --git a/core/argument.sh b/core/argument.sh new file mode 100644 index 0000000..1588b51 --- /dev/null +++ b/core/argument.sh @@ -0,0 +1,183 @@ +#!/bin/bash +# core/argument.sh - version/help/argument parsing +# Migrated verbatim from install.sh (lines 38-41,43-74,75-213,215-234). +version() { + echo "version: 2.6" + echo "updated date: 2022-09-03" +} +Show_Help() { + version + echo "Usage: $0 command ...[parameters].... + --help, -h Show this help message, More: https://oneinstack.com/auto + --version, -v Show version info + --nginx_option [1-2] Install Nginx server version + --php_option [1-3] Install PHP version + --mphp_ver [74/80/81] Install another PHP version (PATH: ${php_install_dir}\${mphp_ver}) + --mphp_addons Only install another PHP addons + --phpcache_option [1-4] Install PHP opcode cache, default: 1 opcache + --php_extensions [ext name] Install PHP extensions, include zendguardloader,ioncube, + sourceguardian,imagick,gmagick,fileinfo,imap,ldap,calendar,phalcon, + yaf,yar,redis,mongodb,swoole,xdebug + --nodejs Install Nodejs + --db_option [1-9] Install DB version + --dbinstallmethod [1-2] DB install method, default: 1 binary install + --dbrootpwd [password] DB super password + --pureftpd Install Pure-Ftpd + --redis Install Redis + --phpmyadmin Install phpMyAdmin + --python Install Python (PATH: ${python_install_dir}) + --ssh_port [No.] SSH port + --iptables Enable iptables (enabled by default on all systems) + --reboot Restart the server after installation + " +} +# core/argument.sh (cont) - parse_arguments (getopt) +# Migrated verbatim from install.sh (lines 75-213); calls handle_ssh_port. +parse_arguments() { +ARG_NUM=$# +TEMP=`getopt -o hvV --long help,version,nginx_option:,php_option:,mphp_ver:,mphp_addons,phpcache_option:,php_extensions:,nodejs,db_option:,dbrootpwd:,dbinstallmethod:,pureftpd,redis,phpmyadmin,python,ssh_port:,iptables,reboot -- "$@" 2>/dev/null` +[ $? != 0 ] && echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 +eval set -- "${TEMP}" +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + Show_Help; exit 0 + ;; + -v|-V|--version) + version; exit 0 + ;; + --nginx_option) + nginx_option=$2; shift 2 + [[ ! ${nginx_option} =~ ^[1-2]$ ]] && { echo "${CWARNING}nginx_option input error! Please only input number 1~2${CEND}"; exit 1; } + [ -e "${nginx_install_dir}/sbin/nginx" ] && { echo "${CWARNING}Nginx already installed! ${CEND}"; unset nginx_option; } + ;; + --php_option) + php_option=$2; shift 2 + [[ ! ${php_option} =~ ^[1-3]$ ]] && { echo "${CWARNING}php_option input error! Please only input number 1~3${CEND}"; exit 1; } + [ -e "${php_install_dir}/bin/phpize" ] && { echo "${CWARNING}PHP already installed! ${CEND}"; unset php_option; } + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ] && [ "${php_option}" == '1' ]; then + echo "${CWARNING}PHP 7.4 is not supported on Ubuntu ${Ubuntu_ver}+, please choose PHP 8.x (php_option 2 or 3)${CEND}"; exit 1; + fi + ;; + --mphp_ver) + mphp_ver=$2; mphp_flag=y; shift 2 + [[ ! "${mphp_ver}" =~ ^(74|80|81)$ ]] && { echo "${CWARNING}mphp_ver input error! Please only input number 74/80/81${CEND}"; exit 1; } + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ] && [ "${mphp_ver}" == '74' ]; then + echo "${CWARNING}mphp 7.4 is not supported on Ubuntu ${Ubuntu_ver}+, please choose 80 or 81${CEND}"; exit 1; + fi + ;; + --mphp_addons) + mphp_addons_flag=y; shift 1 + ;; + --phpcache_option) + phpcache_option=$2; shift 2 + ;; + --php_extensions) + php_extensions=$2; shift 2 + [ -n "`echo ${php_extensions} | grep -w zendguardloader`" ] && pecl_zendguardloader=1 + [ -n "`echo ${php_extensions} | grep -w ioncube`" ] && pecl_ioncube=1 + [ -n "`echo ${php_extensions} | grep -w sourceguardian`" ] && pecl_sourceguardian=1 + [ -n "`echo ${php_extensions} | grep -w imagick`" ] && pecl_imagick=1 + [ -n "`echo ${php_extensions} | grep -w gmagick`" ] && pecl_gmagick=1 + [ -n "`echo ${php_extensions} | grep -w fileinfo`" ] && pecl_fileinfo=1 + [ -n "`echo ${php_extensions} | grep -w imap`" ] && pecl_imap=1 + [ -n "`echo ${php_extensions} | grep -w ldap`" ] && pecl_ldap=1 + [ -n "`echo ${php_extensions} | grep -w calendar`" ] && pecl_calendar=1 + [ -n "`echo ${php_extensions} | grep -w phalcon`" ] && pecl_phalcon=1 + [ -n "`echo ${php_extensions} | grep -w yaf`" ] && pecl_yaf=1 + [ -n "`echo ${php_extensions} | grep -w yar`" ] && pecl_yar=1 + [ -n "`echo ${php_extensions} | grep -w redis`" ] && pecl_redis=1 + [ -n "`echo ${php_extensions} | grep -w mongodb`" ] && pecl_mongodb=1 + [ -n "`echo ${php_extensions} | grep -w swoole`" ] && pecl_swoole=1 + [ -n "`echo ${php_extensions} | grep -w xdebug`" ] && pecl_xdebug=1 + ;; + --nodejs) + nodejs_flag=y; shift 1 + [ -e "${nodejs_install_dir}/bin/node" ] && { echo "${CWARNING}Nodejs already installed! ${CEND}"; unset nodejs_flag; } + ;; + --db_option) + db_option=$2; shift 2 + if [[ "${db_option}" =~ ^[1-5]$ ]]; then + [ -d "${db_install_dir}/support-files" ] && { echo "${CWARNING}MySQL/MariaDB already installed! ${CEND}"; unset db_option; } + elif [[ "${db_option}" =~ ^[6-8]$ ]]; then + [ -e "${pgsql_install_dir}/bin/psql" ] && { echo "${CWARNING}PostgreSQL already installed! ${CEND}"; unset db_option; } + elif [ "${db_option}" == '9' ]; then + [ -e "${mongo_install_dir}/bin/mongo" ] && { echo "${CWARNING}MongoDB already installed! ${CEND}"; unset db_option; } + else + echo "${CWARNING}db_option input error! Please only input number 1~9${CEND}" + exit 1 + fi + ;; + --dbrootpwd) + dbrootpwd=$2; shift 2 + dbpostgrespwd="${dbrootpwd}" + dbmongopwd="${dbrootpwd}" + ;; + --dbinstallmethod) + dbinstallmethod=$2; shift 2 + [[ ! ${dbinstallmethod} =~ ^[1-2]$ ]] && { echo "${CWARNING}dbinstallmethod input error! Please only input number 1~2${CEND}"; exit 1; } + ;; + --pureftpd) + pureftpd_flag=y; shift 1 + [ -e "${pureftpd_install_dir}/sbin/pure-ftpwho" ] && { echo "${CWARNING}Pure-FTPd already installed! ${CEND}"; unset pureftpd_flag; } + ;; + --redis) + redis_flag=y; shift 1 + [ -e "${redis_install_dir}/bin/redis-server" ] && { echo "${CWARNING}redis-server already installed! ${CEND}"; unset redis_flag; } + ;; + --phpmyadmin) + phpmyadmin_flag=y; shift 1 + [ -d "${wwwroot_dir}/default/phpMyAdmin" ] && { echo "${CWARNING}phpMyAdmin already installed! ${CEND}"; unset phpmyadmin_flag; } + ;; + --python) + python_flag=y; shift 1 + ;; + --ssh_port) + ssh_port=$2; shift 2 + ;; + --iptables) + iptables_flag=y; shift 1 + ;; + --reboot) + reboot_flag=y; shift 1 + ;; + --) + shift + ;; + *) + echo "${CWARNING}ERROR: unknown argument! ${CEND}" && Show_Help && exit 1 + ;; + esac +done + # Default-enable iptables for every supported system. ServerStack only + # supports Debian/Ubuntu (firewalld/ufw removed), so iptables is the sole + # firewall; non-interactive installs that omit --iptables still get it. A + # user can still answer 'n' in the interactive menu to opt out. + iptables_flag=${iptables_flag:-y} + # SSH port handling (migrated verbatim, lines 215-234) + handle_ssh_port +} + +handle_ssh_port() { +# Use default SSH port 22. If you use another SSH port on your server +if [ -e "/etc/ssh/sshd_config" ]; then + [ -z "`grep ^Port /etc/ssh/sshd_config`" ] && now_ssh_port=22 || now_ssh_port=`grep ^Port /etc/ssh/sshd_config | awk '{print $2}' | head -1` + while :; do echo + [ ${ARG_NUM} == 0 ] && read -e -p "Please input SSH port(Default: ${now_ssh_port}): " ssh_port + ssh_port=${ssh_port:-${now_ssh_port}} + if [ ${ssh_port} -eq 22 >/dev/null 2>&1 -o ${ssh_port} -gt 1024 >/dev/null 2>&1 -a ${ssh_port} -lt 65535 >/dev/null 2>&1 ]; then + break + else + echo "${CWARNING}input error! Input range: 22,1025~65534${CEND}" + exit 1 + fi + done + + if [ -z "`grep ^Port /etc/ssh/sshd_config`" -a "${ssh_port}" != '22' ]; then + sed -i "s@^#Port.*@&\nPort ${ssh_port}@" /etc/ssh/sshd_config + elif [ -n "`grep ^Port /etc/ssh/sshd_config`" ]; then + sed -i "s@^Port.*@Port ${ssh_port}@" /etc/ssh/sshd_config + fi +fi +} diff --git a/core/demo.sh b/core/demo.sh new file mode 100644 index 0000000..d647978 --- /dev/null +++ b/core/demo.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +DEMO() { + pushd ${oneinstack_dir}/src > /dev/null + if [ ! -e ${wwwroot_dir}/default/index.html ]; then + [ "${IPADDR_COUNTRY}"x == "CN"x ] && /bin/cp ${oneinstack_dir}/config/index_cn.html ${wwwroot_dir}/default/index.html || /bin/cp ${oneinstack_dir}/config/index.html ${wwwroot_dir}/default + fi + + if [ -e "${php_install_dir}/bin/php" ]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/xprober.php && Download_src + /bin/cp xprober.php ${wwwroot_dir}/default + + echo "" > ${wwwroot_dir}/default/phpinfo.php + case "${phpcache_option}" in + 1) + src_url=http://mirrors.linuxeye.com/oneinstack/src/ocp.php && Download_src + /bin/cp ocp.php ${wwwroot_dir}/default + ;; + 2) + sed -i 's@Opcache@APC@' ${wwwroot_dir}/default/index.html + ;; + 3) + sed -i 's@Opcache@xcache@' ${wwwroot_dir}/default/index.html + ;; + 4) + /bin/cp eaccelerator-*/control.php ${wwwroot_dir}/default + sed -i 's@Opcache@eAccelerator@' ${wwwroot_dir}/default/index.html + ;; + *) + sed -i 's@Opcache@@' ${wwwroot_dir}/default/index.html + ;; + esac + fi + chown -R ${run_user}:${run_group} ${wwwroot_dir}/default + [ -e /bin/systemctl ] && systemctl daemon-reload + popd > /dev/null +} diff --git a/core/environment.sh b/core/environment.sh new file mode 100644 index 0000000..1e64e28 --- /dev/null +++ b/core/environment.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# core/environment.sh - environment init, OS check, pre-install prep +# Migrated verbatim from install.sh (lines 12-20,22-23,32-36,693-697,699-713,715-725). +init_environment() { +clear +printf " +####################################################################### +# ServerStack for Debian 9+ and Ubuntu 16+ # +# For more information please visit https://oneinstack.com # +####################################################################### +" +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } +# bin/install.sh already sets oneinstack_dir to the project root and cd's there. +# Derive it robustly from THIS script's own location only as a fallback, so the +# relative sources (./lib, ./config, ./modules) always resolve to the project +# root instead of breaking into bin/ when $0 points at bin/install.sh. +if [ -z "${oneinstack_dir}" ] || [ ! -d "${oneinstack_dir}/lib" ]; then + oneinstack_dir="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)" +fi +cd "${oneinstack_dir}" || exit 1 +} + +# init_variables: generate random credentials. Runs AFTER load_configs so the +# fresh random values intentionally override any dbrootpwd stored in +# config/options.conf (matches the original install.sh ordering: lines 32-36 run +# after the config/options.conf source at lines 24-30). +init_variables() { +dbrootpwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` +dbpostgrespwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` +dbmongopwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` +xcachepwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` +dbinstallmethod=1 +} +# get_local_ipaddr: resolve the server's primary (outbound) IPv4 address with pure +# shell, so the install summary never ends up with an EMPTY IP that produces broken +# URLs like "http:///ocp.php". The legacy ./lib/py/get_ipaddr.py relied on a `python` +# interpreter (via its shebang) which is absent on Ubuntu 22.04+ (only `python3` +# exists); when that script silently failed, IPADDR came back empty. This shell +# implementation is interpreter-independent and falls back through several methods. +get_local_ipaddr() { + local ip="" + # 1) Source address the kernel would use to reach the public Internet. + if command -v ip >/dev/null 2>&1; then + ip=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}') + fi + # 2) First address reported by `hostname -I` (already skips 127.0.0.1 normally). + if [ -z "$ip" ] && command -v hostname >/dev/null 2>&1; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}') + fi + # 3) First global (non-loopback) IPv4 from `ip addr`. + if [ -z "$ip" ] && command -v ip >/dev/null 2>&1; then + ip=$(ip -o -4 addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n1) + fi + # 4) Last resort. + [ -z "$ip" ] && ip="127.0.0.1" + # On a VPC / private-network instance the local IP is an RFC1918 address that + # is NOT reachable from outside the VPC. When we already resolved the public IP + # (PUBLIC_IPADDR, used for mirror selection) prefer it for the control-panel + # URLs so they are actually clickable from the Internet. If the public IP is + # unavailable (no egress, etc.) we keep the private IP as a safe fallback. + case "$ip" in + 10.*|172.1[6-9].*|172.2[0-9].*|172.3[01].*|192.168.*) + [ -n "${PUBLIC_IPADDR}" ] && ip="${PUBLIC_IPADDR}" ;; + esac + echo "$ip" +} +# core/environment.sh (cont) - prepare_install +# Migrated verbatim from install.sh (lines 693-697,699-713,715-725). +prepare_install() { +if [[ ${nginx_option} =~ ^[1-2]$ ]]; then + [ ! -d ${wwwroot_dir}/default ] && mkdir -p ${wwwroot_dir}/default + [ ! -d ${wwwlogs_dir} ] && mkdir -p ${wwwlogs_dir} +fi +[ -d /data ] && chmod 755 /data +# install wget gcc curl python3 +if [ ! -e ~/.oneinstack ]; then + downloadDepsSrc=1 + echo "${CMSG}Updating apt package lists (this may take a few minutes)...${CEND}" + apt-get -y update 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + echo "${CMSG}Installing base tools (wget gcc curl python3)...${CEND}" + ${PM} -y install wget gcc curl python3 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + clear +fi + +# Make sure a `python` interpreter is available for the legacy *.py helpers +# (get_public_ipaddr.py / get_ipaddr_state.py) regardless of whether the OS ships +# `python` (Ubuntu 22.04+ only provides `python3`). Create the symlink UNCONDITIONALLY +# here (not gated by the first-install ~/.oneinstack check) so those scripts keep +# working on every run and on re-installs. +if [ ! -e "/usr/bin/python" ] && command -v python3 >/dev/null 2>&1; then + ln -s "$(command -v python3)" /usr/bin/python +fi + +# get the IP information +# Resolve the PUBLIC IP first so get_local_ipaddr() can prefer it on private / +# VPC networks (where the local IP is not externally reachable). Then the local +# IP for the summary URLs, then the country code from the public IP. +PUBLIC_IPADDR=$(./lib/py/get_public_ipaddr.py) +IPADDR=$(get_local_ipaddr) +IPADDR_COUNTRY=$(./lib/py/get_ipaddr_state.py ${PUBLIC_IPADDR}) +# openSSL +. ./lib/openssl.sh + +# Check download source packages +. ./lib/check_download.sh + +[ "${armplatform}" == "y" ] && dbinstallmethod=2 +checkDownload 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + +# get OS Memory +. ./lib/memory.sh +} + +# check_environment: lightweight guard that the OS was detected. +# (check_os.sh already hard-exits on unsupported OS during load_configs.) +check_environment() { + if [ -z "${PM}" ] || [ -z "${Family}" ]; then + error_exit "Unsupported operating system or system detection failed." + fi +} diff --git a/core/init.sh b/core/init.sh new file mode 100644 index 0000000..fda24a9 --- /dev/null +++ b/core/init.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# core/init.sh - OS hardening + base dependency install +# Migrated verbatim from install.sh (lines 727-746). tee overwrite fixed to tee -a. +init_os() { + # Check binary dependencies packages + . ./lib/check_sw.sh + case "${Family}" in + "debian") + installDepsDebian 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + . core/os/init_Debian.sh 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + ;; + "ubuntu") + installDepsUbuntu 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + . core/os/init_Ubuntu.sh 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + ;; + esac + # Install dependencies from source package + installDepsBySrc 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log +} +# core/init.sh (cont) - prereqs: OpenSSL + Jemalloc +# Migrated verbatim from install.sh (lines 748-758). +install_prereqs() { +# start Time +startTime=`date +%s` + +# openSSL +Install_openSSL | tee -a ${oneinstack_dir}/runtime/install.log + +# Jemalloc +if [[ ${nginx_option} =~ ^[1-3]$ ]] || [[ "${db_option}" =~ ^[1-9]$|^1[0-2]$ ]]; then + . modules/web/jemalloc.sh + Install_Jemalloc | tee -a ${oneinstack_dir}/runtime/install.log +fi +} diff --git a/core/installer.sh b/core/installer.sh new file mode 100644 index 0000000..cc7c9ad --- /dev/null +++ b/core/installer.sh @@ -0,0 +1,219 @@ +#!/bin/bash +# core/installer.sh - install orchestration (logic unchanged) +# Migrated verbatim from install.sh. + +PHP_addons() { + # PHP opcode cache + case "${phpcache_option}" in + 1) + run_install "modules/php-addons/zendopcache.sh" "Install_ZendOPcache" + ;; + 2) + run_install "modules/php-addons/apcu.sh" "Install_APCU" + ;; + 3) + run_install "modules/php-addons/xcache.sh" "Install_XCache" + ;; + 4) + run_install "modules/php-addons/eaccelerator.sh" "Install_eAccelerator" + ;; + esac + + # ZendGuardLoader + if [ "${pecl_zendguardloader}" == '1' ]; then + run_install "modules/php-addons/ZendGuardLoader.sh" "Install_ZendGuardLoader" + fi + + # ioncube + if [ "${pecl_ioncube}" == '1' ]; then + run_install "modules/php-addons/ioncube.sh" "Install_ionCube" + fi + + # SourceGuardian + if [ "${pecl_sourceguardian}" == '1' ]; then + run_install "modules/php-addons/sourceguardian.sh" "Install_SourceGuardian" + fi + + # imagick + if [ "${pecl_imagick}" == '1' ]; then + run_install "modules/image/ImageMagick.sh" "Install_ImageMagick" + Install_pecl_imagick 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + fi + + # gmagick + if [ "${pecl_gmagick}" == '1' ]; then + run_install "modules/image/GraphicsMagick.sh" "Install_GraphicsMagick" + Install_pecl_gmagick 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + fi + + # fileinfo + if [ "${pecl_fileinfo}" == '1' ]; then + run_install "modules/php-addons/pecl_fileinfo.sh" "Install_pecl_fileinfo" + fi + + # imap + if [ "${pecl_imap}" == '1' ]; then + run_install "modules/php-addons/pecl_imap.sh" "Install_pecl_imap" + fi + + # ldap + if [ "${pecl_ldap}" == '1' ]; then + run_install "modules/php-addons/pecl_ldap.sh" "Install_pecl_ldap" + fi + + # calendar + if [ "${pecl_calendar}" == '1' ]; then + run_install "modules/php-addons/pecl_calendar.sh" "Install_pecl_calendar" + fi + + # phalcon + if [ "${pecl_phalcon}" == '1' ]; then + run_install "modules/php-addons/pecl_phalcon.sh" "Install_pecl_phalcon" + fi + + # yaf + if [ "${pecl_yaf}" == '1' ]; then + run_install "modules/php-addons/pecl_yaf.sh" "Install_pecl_yaf" + fi + + # yar + if [ "${pecl_yar}" == '1' ]; then + run_install "modules/php-addons/pecl_yar.sh" "Install_pecl_yar" + fi + + # pecl_redis + if [ "${pecl_redis}" == '1' ]; then + run_install "modules/cache/redis.sh" "Install_pecl_redis" + fi + + # pecl_mongodb + if [ "${pecl_mongodb}" == '1' ]; then + run_install "modules/php-addons/pecl_mongodb.sh" "Install_pecl_mongodb" + fi + + # swoole + if [ "${pecl_swoole}" == '1' ]; then + run_install "modules/php-addons/pecl_swoole.sh" "Install_pecl_swoole" + fi + + # xdebug + if [ "${pecl_xdebug}" == '1' ]; then + run_install "modules/php-addons/pecl_xdebug.sh" "Install_pecl_xdebug" + fi + + # pecl_pgsql + if [ -e "${pgsql_install_dir}/bin/psql" ]; then + run_install "modules/php-addons/pecl_pgsql.sh" "Install_pecl_pgsql" + fi +} + + +install_modules() { +# Database +case "${db_option}" in + 1) + run_install "modules/db/mysql-8.0.sh" "Install_MySQL80" + ;; + 2) + run_install "modules/db/mysql-5.7.sh" "Install_MySQL57" + ;; + 3) + run_install "modules/db/mariadb-10.11.sh" "Install_MariaDB1011" + ;; + 4) + run_install "modules/db/mariadb-11.8.sh" "Install_MariaDB118" + ;; + 5) + run_install "modules/db/mariadb-12.3.sh" "Install_MariaDB123" + ;; + 6) + pgsql_ver=${pgsql1514_ver} + run_install "modules/db/postgresql.sh" "Install_PostgreSQL" + ;; + 7) + pgsql_ver=${pgsql1610_ver} + run_install "modules/db/postgresql.sh" "Install_PostgreSQL" + ;; + 8) + pgsql_ver=${pgsql176_ver} + run_install "modules/db/postgresql.sh" "Install_PostgreSQL" + ;; + 9) + run_install "modules/db/mongodb.sh" "Install_MongoDB" + ;; +esac + +# Nginx server +case "${nginx_option}" in + 1) + run_install "modules/web/nginx.sh" "Install_Nginx" + ;; +esac + +# PHP +case "${php_option}" in + 1) + # On Ubuntu 24+ PHP 7.4 does not compile against the system libicu; the + # guard here is a last-resort safety net in case validation was bypassed. + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ]; then + echo "${CWARNING}Skipping PHP 7.4: not supported on Ubuntu ${Ubuntu_ver}+. Use PHP 8.x.${CEND}" + else + run_install "modules/php/php-7.4.sh" "Install_PHP74" + fi + ;; + 2) + run_install "modules/php/php-8.0.sh" "Install_PHP80" + ;; + 3) + run_install "modules/php/php-8.1.sh" "Install_PHP81" + ;; +esac +[ "${mphp_addons_flag}" != 'y' ] && PHP_addons + +if [ "${mphp_flag}" == 'y' ]; then + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ] && [ "${mphp_ver}" == '74' ]; then + echo "${CWARNING}Skipping mphp 7.4: not supported on Ubuntu ${Ubuntu_ver}+. Use 80 or 81.${CEND}" + else + run_install "modules/php/mphp.sh" "Install_MPHP" + php_install_dir=${php_install_dir}${mphp_ver} + PHP_addons + fi +fi + +# Nodejs +if [ "${nodejs_flag}" == 'y' ]; then + run_install "modules/lang/nodejs.sh" "Install_Nodejs" +fi + +# Pure-FTPd +if [ "${pureftpd_flag}" == 'y' ]; then + run_install "modules/ftp/pureftpd.sh" "Install_PureFTPd" +fi + +# phpMyAdmin +if [ "${phpmyadmin_flag}" == 'y' ]; then + run_install "modules/app/phpmyadmin.sh" "Install_phpMyAdmin" +fi + +# redis +if [ "${redis_flag}" == 'y' ]; then + run_install "modules/cache/redis.sh" "Install_redis_server" +fi +# Python +if [ "${python_flag}" == 'y' ]; then + run_install "modules/lang/python.sh" "Install_Python" +fi +} + +# configure_modules: deploy default demo site and re-read install dirs. +# Migrated verbatim from install.sh (lines 1102-1109). +configure_modules() { +# index example +if [ -d "${wwwroot_dir}/default" ]; then + . core/demo.sh + DEMO 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log +fi + +# get web_install_dir and db_install_dir +. lib/check_dir.sh +} diff --git a/core/menu.sh b/core/menu.sh new file mode 100644 index 0000000..ecd5543 --- /dev/null +++ b/core/menu.sh @@ -0,0 +1,297 @@ +#!/bin/bash +# core/menu.sh - interactive menu +# Migrated verbatim from install.sh (lines 236-691). Logic unchanged. +show_menu() { +if [ ${ARG_NUM} == 0 ]; then + if [ ! -e ~/.oneinstack ]; then + # check iptables + # Default to 'y': ServerStack only supports Debian/Ubuntu (firewalld/ufw + # were removed), so iptables is the firewall for every supported system. + # The user can still answer 'n' to opt out. + while :; do echo + read -e -p "Do you want to enable iptables? [y/n] (default y):" iptables_flag + [ -z "${iptables_flag}" ] && iptables_flag=y + if [[ ! ${iptables_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done + fi + + # check Web server + while :; do echo + read -e -p "Do you want to install Web server? [y/n]: " web_flag + if [[ ! ${web_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + if [ "${web_flag}" == 'y' ]; then + # Nginx + while :; do echo + echo 'Please select Nginx server:' + echo -e "\t${CMSG}1${CEND}. Install Nginx" + echo -e "\t${CMSG}2${CEND}. Do not install" + read -e -p "Please input a number:(Default 1 press Enter)" nginx_option + nginx_option=${nginx_option:-1} + if [[ ! ${nginx_option} =~ ^[1-2]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~2${CEND}" + else + [ "${nginx_option}" != '2' -a -e "${nginx_install_dir}/sbin/nginx" ] && { echo "${CWARNING}Nginx already installed! ${CEND}"; unset nginx_option; } + break + fi + done + fi + break + fi + done + + # choice database + while :; do echo + read -e -p "Do you want to install Database? [y/n]: " db_flag + if [[ ! ${db_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + if [ "${db_flag}" == 'y' ]; then + while :; do echo + echo 'Please select a version of the Database:' + echo -e "\t${CMSG} 1${CEND}. Install MySQL-8.0" + echo -e "\t${CMSG} 2${CEND}. Install MySQL-5.7" + echo -e "\t${CMSG} 3${CEND}. Install MariaDB-10.11" + echo -e "\t${CMSG} 4${CEND}. Install MariaDB-11.8" + echo -e "\t${CMSG} 5${CEND}. Install MariaDB-12.3" + echo -e "\t${CMSG} 6${CEND}. Install PostgreSQL-15.14" + echo -e "\t${CMSG} 7${CEND}. Install PostgreSQL-16.10" + echo -e "\t${CMSG} 8${CEND}. Install PostgreSQL-17.6" + echo -e "\t${CMSG} 9${CEND}. Install MongoDB" + read -e -p "Please input a number:(Default 3 press Enter) " db_option + db_option=${db_option:-3} + if [[ "${db_option}" =~ ^[1-9]$ ]]; then + if [[ "${db_option}" =~ ^[6-8]$ ]]; then + [ -e "${pgsql_install_dir}/bin/psql" ] && { echo "${CWARNING}PostgreSQL already installed! ${CEND}"; unset db_option; break; } + elif [ "${db_option}" == '9' ]; then + [ -e "${mongo_install_dir}/bin/mongo" ] && { echo "${CWARNING}MongoDB already installed! ${CEND}"; unset db_option; break; } + else + [ -d "${db_install_dir}/support-files" ] && { echo "${CWARNING}MySQL/MariaDB already installed! ${CEND}"; unset db_option; break; } + fi + while :; do + if [[ "${db_option}" =~ ^[6-8]$ ]]; then + read -e -p "Please input the postgres password of PostgreSQL(default: ${dbpostgrespwd}): " dbpwd + dbpwd=${dbpwd:-${dbpostgrespwd}} + elif [ "${db_option}" == '9' ]; then + read -e -p "Please input the root password of MongoDB(default: ${dbmongopwd}): " dbpwd + dbpwd=${dbpwd:-${dbmongopwd}} + else + read -e -p "Please input the root password of MySQL/MariaDB(default: ${dbrootpwd}): " dbpwd + dbpwd=${dbpwd:-${dbrootpwd}} + fi + [ -n "`echo ${dbpwd} | grep '[+|&]'`" ] && { echo "${CWARNING}input error,not contain a plus sign (+) and & ${CEND}"; continue; } + if (( ${#dbpwd} >= 5 )); then + if [[ "${db_option}" =~ ^[6-8]$ ]]; then + dbpostgrespwd=${dbpwd} + elif [ "${db_option}" == '9' ]; then + dbmongopwd=${dbpwd} + else + dbrootpwd=${dbpwd} + fi + break + else + echo "${CWARNING}password least 5 characters! ${CEND}" + fi + done + # choose install methods + if [[ "${db_option}" =~ ^[1-5]$ ]]; then + while :; do echo + echo "Please choose installation of the database:" + echo -e "\t${CMSG}1${CEND}. Install database from binary package." + echo -e "\t${CMSG}2${CEND}. Install database from source package." + read -e -p "Please input a number:(Default 1 press Enter) " dbinstallmethod + dbinstallmethod=${dbinstallmethod:-1} + if [[ ! ${dbinstallmethod} =~ ^[1-2]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~2${CEND}" + else + break + fi + done + fi + break + else + echo "${CWARNING}input error! Please only input number 1~9${CEND}" + fi + done + fi + break + fi + done + + # choice php + while :; do echo + read -e -p "Do you want to install PHP? [y/n]: " php_flag + if [[ ! ${php_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + if [ "${php_flag}" == 'y' ]; then + [ -e "${php_install_dir}/bin/phpize" ] && { echo "${CWARNING}PHP already installed! ${CEND}"; unset php_option; break; } + while :; do echo + echo 'Please select a version of the PHP:' + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ]; then + echo -e "\t${CMSG} 1${CEND}. Install php-7.4 ${CWARNING}(unavailable on Ubuntu ${Ubuntu_ver}+, only PHP 8.x is supported)${CEND}" + echo -e "\t${CMSG} 2${CEND}. Install php-8.0" + echo -e "\t${CMSG} 3${CEND}. Install php-8.1" + else + echo -e "\t${CMSG} 1${CEND}. Install php-7.4" + echo -e "\t${CMSG} 2${CEND}. Install php-8.0" + echo -e "\t${CMSG} 3${CEND}. Install php-8.1" + fi + read -e -p "Please input a number:(Default 1 press Enter) " php_option + php_option=${php_option:-1} + if [[ ! ${php_option} =~ ^[1-3]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~3${CEND}" + elif [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ] && [ "${php_option}" == '1' ]; then + echo "${CWARNING}PHP 7.4 is not supported on Ubuntu ${Ubuntu_ver}+, please select PHP 8.x (option 2 or 3)${CEND}" + else + break + fi + done + fi + break + fi + done + + # check php ver + if [ -e "${php_install_dir}/bin/phpize" ]; then + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + fi + + # PHP opcode cache and extensions + if [[ ${php_option} =~ ^[1-3]$ ]] || [ -e "${php_install_dir}/bin/phpize" ]; then + while :; do echo + read -e -p "Do you want to install opcode cache of the PHP? [y/n]: " phpcache_flag + if [[ ! ${phpcache_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + if [ "${phpcache_flag}" == 'y' ]; then + if [[ ${php_option} =~ ^[1-3]$ ]] || [[ "${PHP_main_ver}" =~ ^7.[0-4]$|^8.[0-1]$ ]]; then + while :; do + echo 'Please select a opcode cache of the PHP:' + echo -e "\t${CMSG}1${CEND}. Install Zend OPcache" + echo -e "\t${CMSG}2${CEND}. Install APCU" + read -e -p "Please input a number:(Default 1 press Enter) " phpcache_option + phpcache_option=${phpcache_option:-1} + if [[ ! ${phpcache_option} =~ ^[1-2]$ ]]; then + echo "${CWARNING}input error! Please only input number 1~2${CEND}" + else + break + fi + done + fi + fi + break + fi + done + # set xcache passwd + if [ "${phpcache_option}" == '3' ]; then + while :; do + read -e -p "Please input xcache admin password: " xcachepwd + (( ${#xcachepwd} >= 5 )) && { xcachepwd_md5=$(echo -n "${xcachepwd}" | md5sum | awk '{print $1}') ; break ; } || echo "${CFAILURE}xcache admin password least 5 characters! ${CEND}" + done + fi + # PHP extension + while :; do + echo + echo 'Please select PHP extensions:' + echo -e "\t${CMSG} 0${CEND}. Do not install" + echo -e "\t${CMSG} 1${CEND}. Install zendguardloader(PHP<=5.6)" + echo -e "\t${CMSG} 2${CEND}. Install ioncube" + echo -e "\t${CMSG} 3${CEND}. Install sourceguardian(PHP<=7.2)" + echo -e "\t${CMSG} 4${CEND}. Install imagick" + echo -e "\t${CMSG} 5${CEND}. Install gmagick" + echo -e "\t${CMSG} 6${CEND}. Install fileinfo" + echo -e "\t${CMSG} 7${CEND}. Install imap" + echo -e "\t${CMSG} 8${CEND}. Install ldap" + echo -e "\t${CMSG} 9${CEND}. Install phalcon(PHP>=5.5)" + echo -e "\t${CMSG}10${CEND}. Install yaf(PHP>=7.0)" + echo -e "\t${CMSG}11${CEND}. Install redis" + echo -e "\t${CMSG}12${CEND}. Install mongodb" + echo -e "\t${CMSG}13${CEND}. Install swoole" + echo -e "\t${CMSG}14${CEND}. Install xdebug(PHP>=5.5)" + read -e -p "Please input numbers:(Default '4 6 11 12' press Enter) " phpext_option + phpext_option=${phpext_option:-'4 6 11 12'} + [ "${phpext_option}" == '0' ] && break + array_phpext=(${phpext_option}) + array_all=(1 2 3 4 5 6 7 8 9 10 11 12 13 14) + for v in ${array_phpext[@]} + do + [ -z "`echo ${array_all[@]} | grep -w ${v}`" ] && phpext_flag=1 + done + if [ "${phpext_flag}" == '1' ]; then + unset phpext_flag + echo; echo "${CWARNING}input error! Please only input number 4 11 12 and so on${CEND}"; echo + continue + else + [ -n "`echo ${array_phpext[@]} | grep -w 1`" ] && pecl_zendguardloader=1 + [ -n "`echo ${array_phpext[@]} | grep -w 2`" ] && pecl_ioncube=1 + [ -n "`echo ${array_phpext[@]} | grep -w 3`" ] && pecl_sourceguardian=1 + [ -n "`echo ${array_phpext[@]} | grep -w 4`" ] && pecl_imagick=1 + [ -n "`echo ${array_phpext[@]} | grep -w 5`" ] && pecl_gmagick=1 + [ -n "`echo ${array_phpext[@]} | grep -w 6`" ] && pecl_fileinfo=1 + [ -n "`echo ${array_phpext[@]} | grep -w 7`" ] && pecl_imap=1 + [ -n "`echo ${array_phpext[@]} | grep -w 8`" ] && pecl_ldap=1 + [ -n "`echo ${array_phpext[@]} | grep -w 9`" ] && pecl_phalcon=1 + [ -n "`echo ${array_phpext[@]} | grep -w 10`" ] && pecl_yaf=1 + [ -n "`echo ${array_phpext[@]} | grep -w 11`" ] && pecl_redis=1 + [ -n "`echo ${array_phpext[@]} | grep -w 12`" ] && pecl_mongodb=1 + [ -n "`echo ${array_phpext[@]} | grep -w 13`" ] && pecl_swoole=1 + [ -n "`echo ${array_phpext[@]} | grep -w 14`" ] && pecl_xdebug=1 + break + fi + done + fi + + # check Nodejs + while :; do echo + read -e -p "Do you want to install Nodejs? [y/n]: " nodejs_flag + if [[ ! ${nodejs_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + [ "${nodejs_flag}" == 'y' -a -e "${nodejs_install_dir}/bin/node" ] && { echo "${CWARNING}Nodejs already installed! ${CEND}"; unset nodejs_flag; } + break + fi + done + + # check Pureftpd + while :; do echo + read -e -p "Do you want to install Pure-FTPd? [y/n]: " pureftpd_flag + if [[ ! ${pureftpd_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + [ "${pureftpd_flag}" == 'y' -a -e "${pureftpd_install_dir}/sbin/pure-ftpwho" ] && { echo "${CWARNING}Pure-FTPd already installed! ${CEND}"; unset pureftpd_flag; } + break + fi + done + + # check phpMyAdmin + if [[ ${php_option} =~ ^[1-3]$ ]] || [ -e "${php_install_dir}/bin/phpize" ]; then + while :; do echo + read -e -p "Do you want to install phpMyAdmin? [y/n]: " phpmyadmin_flag + if [[ ! ${phpmyadmin_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + [ "${phpmyadmin_flag}" == 'y' -a -d "${wwwroot_dir}/default/phpMyAdmin" ] && { echo "${CWARNING}phpMyAdmin already installed! ${CEND}"; unset phpmyadmin_flag; } + break + fi + done + fi + + # check redis + while :; do echo + read -e -p "Do you want to install redis-server? [y/n]: " redis_flag + if [[ ! ${redis_flag} =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + [ "${redis_flag}" == 'y' -a -e "${redis_install_dir}/bin/redis-server" ] && { echo "${CWARNING}redis-server already installed! ${CEND}"; unset redis_flag; } + break + fi + done +fi +} diff --git a/core/os/init_Debian.sh b/core/os/init_Debian.sh new file mode 100644 index 0000000..83d183e --- /dev/null +++ b/core/os/init_Debian.sh @@ -0,0 +1,137 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# Custom profile +cat > /etc/profile.d/oneinstack.sh << EOF +HISTSIZE=10000 +PS1='\${debian_chroot:+(\$debian_chroot)}\\[\\e[1;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ ' +HISTTIMEFORMAT="%F %T \$(whoami) " + +alias l='ls -AFhlt --color=auto' +alias lh='l | head' +alias ll='ls -l --color=auto' +alias ls='ls --color=auto' +alias vi=vim + +GREP_OPTIONS="--color=auto" +alias grep='grep --color' +alias egrep='egrep --color' +alias fgrep='fgrep --color' +EOF + +sed -i 's@^"syntax on@syntax on@' /etc/vim/vimrc + +# history +[ -z "$(grep history-timestamp ~/.bashrc)" ] && echo "PROMPT_COMMAND='{ msg=\$(history 1 | { read x y; echo \$y; });user=\$(whoami); echo \$(date \"+%Y-%m-%d %H:%M:%S\"):\$user:\`pwd\`/:\$msg ---- \$(who am i); } >> /tmp/\`hostname\`.\`whoami\`.history-timestamp'" >> ~/.bashrc + +# /etc/security/limits.conf +[ -e /etc/security/limits.d/*nproc.conf ] && rename nproc.conf nproc.conf_bk /etc/security/limits.d/*nproc.conf +[ -z "$(grep 'session required pam_limits.so' /etc/pam.d/common-session)" ] && echo "session required pam_limits.so" >> /etc/pam.d/common-session +sed -i '/^# End of file/,$d' /etc/security/limits.conf +cat >> /etc/security/limits.conf < /etc/resolv.conf << EOF +#nameserver 114.114.114.114 +#nameserver 8.8.8.8 +#EOF + +# /etc/sysctl.conf +[ -z "$(grep 'fs.file-max' /etc/sysctl.conf)" ] && cat >> /etc/sysctl.conf << EOF +fs.file-max = 1000000 +fs.inotify.max_user_instances = 8192 +net.ipv4.tcp_syncookies = 1 +net.ipv4.tcp_fin_timeout = 30 +net.ipv4.tcp_tw_reuse = 1 +net.ipv4.ip_local_port_range = 1024 65000 +net.ipv4.tcp_max_syn_backlog = 16384 +net.ipv4.tcp_max_tw_buckets = 6000 +net.ipv4.route.gc_timeout = 100 +net.ipv4.tcp_syn_retries = 1 +net.ipv4.tcp_synack_retries = 1 +net.core.somaxconn = 32768 +net.core.netdev_max_backlog = 32768 +net.ipv4.tcp_timestamps = 0 +net.ipv4.tcp_max_orphans = 32768 +EOF +sysctl -p + +sed -i 's@^ACTIVE_CONSOLES.*@ACTIVE_CONSOLES="/dev/tty[1-2]"@' /etc/default/console-setup +sed -i 's@^# en_US.UTF-8@en_US.UTF-8@' /etc/locale.gen +init q + +# Update time +if [ -e "$(which ntpdate)" ]; then + ntpdate -u pool.ntp.org + [ ! -e "/var/spool/cron/crontabs/root" -o -z "$(grep ntpdate /var/spool/cron/crontabs/root 2>/dev/null)" ] && { echo "*/20 * * * * $(which ntpdate) -u pool.ntp.org > /dev/null 2>&1" >> /var/spool/cron/crontabs/root;chmod 600 /var/spool/cron/crontabs/root; } +fi + +# iptables +if [ "${iptables_flag}" == 'y' ]; then + echo "${CMSG}Installing iptables firewall tooling...${CEND}" + apt-get -y install debconf-utils + echo iptables-persistent iptables-persistent/autosave_v4 boolean true | debconf-set-selections + echo iptables-persistent iptables-persistent/autosave_v6 boolean true | debconf-set-selections + apt-get -y install iptables-persistent + if [ -e "/etc/iptables/rules.v4" ] && [ -n "$(grep '^:INPUT DROP' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 22 -j ACCEPT' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 80 -j ACCEPT' /etc/iptables/rules.v4)" ]; then + IPTABLES_STATUS=yes + else + IPTABLES_STATUS=no + fi + + if [ "${IPTABLES_STATUS}" == "no" ]; then + cat > /etc/iptables/rules.v4 << EOF +# Firewall configuration written by system-config-securitylevel +# Manual customization of this file is not recommended. +*filter +:INPUT DROP [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:syn-flood - [0:0] +-A INPUT -i lo -j ACCEPT +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT +COMMIT +EOF + fi + + FW_PORT_FLAG=$(grep -ow "dport ${ssh_port}" /etc/iptables/rules.v4) + [ -z "${FW_PORT_FLAG}" -a "${ssh_port}" != "22" ] && sed -i "s@dport 22 -j ACCEPT@&\n-A INPUT -p tcp -m state --state NEW -m tcp --dport ${ssh_port} -j ACCEPT@" /etc/iptables/rules.v4 + iptables-restore < /etc/iptables/rules.v4 + /bin/cp /etc/iptables/rules.v{4,6} + sed -i 's@icmp@icmpv6@g' /etc/iptables/rules.v6 + ip6tables-restore < /etc/iptables/rules.v6 + ip6tables-save > /etc/iptables/rules.v6 +fi +service rsyslog restart +service ssh restart + +. /etc/profile +. ~/.bashrc diff --git a/core/os/init_Ubuntu.sh b/core/os/init_Ubuntu.sh new file mode 100644 index 0000000..fb00c63 --- /dev/null +++ b/core/os/init_Ubuntu.sh @@ -0,0 +1,137 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# Custom profile +cat > /etc/profile.d/oneinstack.sh << EOF +HISTSIZE=10000 +HISTTIMEFORMAT="%F %T \$(whoami) " + +alias l='ls -AFhlt --color=auto' +alias lh='l | head' +alias ll='ls -l --color=auto' +alias ls='ls --color=auto' +alias vi=vim + +GREP_OPTIONS="--color=auto" +alias grep='grep --color' +alias egrep='egrep --color' +alias fgrep='fgrep --color' +EOF + +sed -i 's@^"syntax on@syntax on@' /etc/vim/vimrc + +# PS1 +[ -z "$(grep ^PS1 ~/.bashrc)" ] && echo "PS1='\${debian_chroot:+(\$debian_chroot)}\\[\\e[1;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> ~/.bashrc + +# history +[ -z "$(grep history-timestamp ~/.bashrc)" ] && echo "PROMPT_COMMAND='{ msg=\$(history 1 | { read x y; echo \$y; });user=\$(whoami); echo \$(date \"+%Y-%m-%d %H:%M:%S\"):\$user:\`pwd\`/:\$msg ---- \$(who am i); } >> /tmp/\`hostname\`.\`whoami\`.history-timestamp'" >> ~/.bashrc + +# /etc/security/limits.conf +[ -e /etc/security/limits.d/*nproc.conf ] && rename nproc.conf nproc.conf_bk /etc/security/limits.d/*nproc.conf +[ -z "$(grep 'session required pam_limits.so' /etc/pam.d/common-session)" ] && echo "session required pam_limits.so" >> /etc/pam.d/common-session +sed -i '/^# End of file/,$d' /etc/security/limits.conf +cat >> /etc/security/limits.conf < /etc/resolv.conf << EOF +#nameserver 114.114.114.114 +#nameserver 8.8.8.8 +#EOF + +# /etc/sysctl.conf +[ -z "$(grep 'fs.file-max' /etc/sysctl.conf)" ] && cat >> /etc/sysctl.conf << EOF +fs.file-max = 1000000 +fs.inotify.max_user_instances = 8192 +net.ipv4.tcp_syncookies = 1 +net.ipv4.tcp_fin_timeout = 30 +net.ipv4.tcp_tw_reuse = 1 +net.ipv4.ip_local_port_range = 1024 65000 +net.ipv4.tcp_max_syn_backlog = 16384 +net.ipv4.tcp_max_tw_buckets = 6000 +net.ipv4.route.gc_timeout = 100 +net.ipv4.tcp_syn_retries = 1 +net.ipv4.tcp_synack_retries = 1 +net.core.somaxconn = 32768 +net.core.netdev_max_backlog = 32768 +net.ipv4.tcp_timestamps = 0 +net.ipv4.tcp_max_orphans = 32768 +EOF +sysctl -p + +sed -i 's@^ACTIVE_CONSOLES.*@ACTIVE_CONSOLES="/dev/tty[1-2]"@' /etc/default/console-setup +locale-gen en_US.UTF-8 +[ -d "/var/lib/locales/supported.d" ] && echo "en_US.UTF-8 UTF-8" > /var/lib/locales/supported.d/local +cat > /etc/default/locale << EOF +LANG=en_US.UTF-8 +LANGUAGE=en_US:en +EOF + +# iptables +if [ "${iptables_flag}" == 'y' ]; then + echo "${CMSG}Installing iptables firewall tooling...${CEND}" + apt-get -y install debconf-utils + echo iptables-persistent iptables-persistent/autosave_v4 boolean true | debconf-set-selections + echo iptables-persistent iptables-persistent/autosave_v6 boolean true | debconf-set-selections + apt-get -y install iptables-persistent + if [ -e "/etc/iptables/rules.v4" ] && [ -n "$(grep '^:INPUT DROP' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 22 -j ACCEPT' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 80 -j ACCEPT' /etc/iptables/rules.v4)" ]; then + IPTABLES_STATUS=yes + else + IPTABLES_STATUS=no + fi + + if [ "${IPTABLES_STATUS}" == "no" ]; then + cat > /etc/iptables/rules.v4 << EOF +# Firewall configuration written by system-config-securitylevel +# Manual customization of this file is not recommended. +*filter +:INPUT DROP [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:syn-flood - [0:0] +-A INPUT -i lo -j ACCEPT +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT +COMMIT +EOF + fi + + FW_PORT_FLAG=$(grep -ow "dport ${ssh_port}" /etc/iptables/rules.v4) + [ -z "${FW_PORT_FLAG}" -a "${ssh_port}" != "22" ] && sed -i "s@dport 22 -j ACCEPT@&\n-A INPUT -p tcp -m state --state NEW -m tcp --dport ${ssh_port} -j ACCEPT@" /etc/iptables/rules.v4 + iptables-restore < /etc/iptables/rules.v4 + /bin/cp /etc/iptables/rules.v{4,6} + sed -i 's@icmp@icmpv6@g' /etc/iptables/rules.v6 + ip6tables-restore < /etc/iptables/rules.v6 + ip6tables-save > /etc/iptables/rules.v6 +fi +service rsyslog restart +service ssh restart + +. /etc/profile +. ~/.bashrc diff --git a/core/service.sh b/core/service.sh new file mode 100644 index 0000000..1a387f7 --- /dev/null +++ b/core/service.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# core/service.sh - start services after install +# Migrated verbatim from install.sh (lines 1117-1124). +start_services() { +# Starting DB +[ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} +[ -d "${db_install_dir}/support-files" ] && [ -z "`ps -ef | grep mysqld_safe | grep -v grep`" ] && service mysqld start + +# reload php +[ -e "${php_install_dir}/sbin/php-fpm" ] && start_service php-fpm reload +[ -n "${mphp_ver}" -a -e "${php_install_dir}${mphp_ver}/sbin/php-fpm" ] && start_service php${mphp_ver}-fpm reload +} + +# start_service: unified systemctl|service dispatcher (de-dup of dual-path lines). +start_service() { + local name="$1" action="$2" + [ -e /bin/systemctl ] && systemctl "${action}" "${name}" || service "${name}" "${action}" +} diff --git a/core/summary.sh b/core/summary.sh new file mode 100644 index 0000000..377f601 --- /dev/null +++ b/core/summary.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# core/summary.sh - installation summary + reboot prompt +# Migrated verbatim from install.sh (lines 1126-1174). Logic unchanged. +print_summary() { +endTime=`date +%s` +((installTime=($endTime-$startTime)/60)) +echo "####################Congratulations########################" +echo "Total OneinStack Install Time: ${CQUESTION}${installTime}${CEND} minutes" +[[ "${nginx_option}" =~ ^[1-2]$ ]] && echo -e "\n$(printf "%-32s" "Nginx install dir":)${CMSG}${web_install_dir}${CEND}" +[[ "${db_option}" =~ ^[1-5]$ ]] && echo -e "\n$(printf "%-32s" "Database install dir:")${CMSG}${db_install_dir}${CEND}" +[[ "${db_option}" =~ ^[1-5]$ ]] && echo "$(printf "%-32s" "Database data dir:")${CMSG}${db_data_dir}${CEND}" +[[ "${db_option}" =~ ^[1-5]$ ]] && echo "$(printf "%-32s" "Database user:")${CMSG}root${CEND}" +[[ "${db_option}" =~ ^[1-5]$ ]] && echo "$(printf "%-32s" "Database password:")${CMSG}${dbrootpwd}${CEND}" +[[ "${db_option}" =~ ^[6-8]$ ]] && echo -e "\n$(printf "%-32s" "PostgreSQL install dir:")${CMSG}${pgsql_install_dir}${CEND}" +[[ "${db_option}" =~ ^[6-8]$ ]] && echo "$(printf "%-32s" "PostgreSQL data dir:")${CMSG}${pgsql_data_dir}${CEND}" +[[ "${db_option}" =~ ^[6-8]$ ]] && echo "$(printf "%-32s" "PostgreSQL user:")${CMSG}postgres${CEND}" +[[ "${db_option}" =~ ^[6-8]$ ]] && echo "$(printf "%-32s" "postgres password:")${CMSG}${dbpostgrespwd}${CEND}" +[ "${db_option}" == '9' ] && echo -e "\n$(printf "%-32s" "MongoDB install dir:")${CMSG}${mongo_install_dir}${CEND}" +[ "${db_option}" == '9' ] && echo "$(printf "%-32s" "MongoDB data dir:")${CMSG}${mongo_data_dir}${CEND}" +[ "${db_option}" == '9' ] && echo "$(printf "%-32s" "MongoDB user:")${CMSG}root${CEND}" +[ "${db_option}" == '9' ] && echo "$(printf "%-32s" "MongoDB password:")${CMSG}${dbmongopwd}${CEND}" +[[ "${php_option}" =~ ^[1-3]$ ]] && echo -e "\n$(printf "%-32s" "PHP install dir:")${CMSG}${php_install_dir}${CEND}" +[ "${phpcache_option}" == '1' ] && echo "$(printf "%-32s" "Opcache Control Panel URL:")${CMSG}http://${IPADDR}/ocp.php${CEND}" +[ "${phpcache_option}" == '2' ] && echo "$(printf "%-32s" "APC Control Panel URL:")${CMSG}http://${IPADDR}/apc.php${CEND}" +[ "${phpcache_option}" == '3' -a -e "${php_install_dir}/etc/php.d/04-xcache.ini" ] && echo "$(printf "%-32s" "xcache Control Panel URL:")${CMSG}http://${IPADDR}/xcache${CEND}" +[ "${phpcache_option}" == '3' -a -e "${php_install_dir}/etc/php.d/04-xcache.ini" ] && echo "$(printf "%-32s" "xcache user:")${CMSG}admin${CEND}" +[ "${phpcache_option}" == '3' -a -e "${php_install_dir}/etc/php.d/04-xcache.ini" ] && echo "$(printf "%-32s" "xcache password:")${CMSG}${xcachepwd}${CEND}" +[ "${phpcache_option}" == '4' -a -e "${php_install_dir}/etc/php.d/02-eaccelerator.ini" ] && echo "$(printf "%-32s" "eAccelerator Control Panel URL:")${CMSG}http://${IPADDR}/control.php${CEND}" +[ "${phpcache_option}" == '4' -a -e "${php_install_dir}/etc/php.d/02-eaccelerator.ini" ] && echo "$(printf "%-32s" "eAccelerator user:")${CMSG}admin${CEND}" +[ "${phpcache_option}" == '4' -a -e "${php_install_dir}/etc/php.d/02-eaccelerator.ini" ] && echo "$(printf "%-32s" "eAccelerator password:")${CMSG}eAccelerator${CEND}" +[ "${pureftpd_flag}" == 'y' ] && echo -e "\n$(printf "%-32s" "Pure-FTPd install dir:")${CMSG}${pureftpd_install_dir}${CEND}" +[ "${pureftpd_flag}" == 'y' ] && echo "$(printf "%-32s" "Create FTP virtual script:")${CMSG}./pureftpd_vhost.sh${CEND}" +[ "${phpmyadmin_flag}" == 'y' ] && echo -e "\n$(printf "%-32s" "phpMyAdmin dir:")${CMSG}${wwwroot_dir}/default/phpMyAdmin${CEND}" +[ "${phpmyadmin_flag}" == 'y' ] && echo "$(printf "%-32s" "phpMyAdmin Control Panel URL:")${CMSG}http://${IPADDR}/phpMyAdmin${CEND}" +[ "${redis_flag}" == 'y' ] && echo -e "\n$(printf "%-32s" "redis install dir:")${CMSG}${redis_install_dir}${CEND}" +if [[ ${nginx_option} =~ ^[1-2]$ ]]; then + echo -e "\n$(printf "%-32s" "Index URL:")${CMSG}http://${IPADDR}/${CEND}" +fi +if [ ${ARG_NUM} == 0 ]; then + while :; do echo + echo "${CMSG}Please restart the server and see if the services start up fine.${CEND}" + read -e -p "Do you want to restart OS ? [y/n]: " reboot_flag + if [[ ! "${reboot_flag}" =~ ^[y,n]$ ]]; then + echo "${CWARNING}input error! Please only input 'y' or 'n'${CEND}" + else + break + fi + done +fi +[ "${reboot_flag}" == 'y' ] && reboot +} diff --git a/core/validator.sh b/core/validator.sh new file mode 100644 index 0000000..c703a1c --- /dev/null +++ b/core/validator.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# core/validator.sh - unified option validation. +# +# The primary validation still happens inline inside parse_arguments and +# show_menu (migrated verbatim, to preserve the exact error messages and the +# "already installed" guards). validate_options() is a final, idempotent +# safety net: it re-checks only options that are still set, using the same +# regexes and messages, so it can never change a valid install path. + +# Validate a single value against an ERE. +# $1 = value, $2 = regex, $3 = error message +is_valid() { + local val="$1" regex="$2" msg="$3" + if [[ "${val}" =~ ${regex} ]]; then + return 0 + fi + echo "${CWARNING}${msg}${CEND}" + return 1 +} + +# Re-validate options that are still set after parse/menu. Empty options +# (e.g. unset because already installed) are skipped. +validate_options() { + _check_opt() { + # $1 = value, $2 = regex, $3 = message + [ -z "$1" ] && return 0 + is_valid "$1" "$2" "$3" || error_exit "$3" + } + + _check_opt "${nginx_option}" '^[1-2]$' "nginx_option input error! Please only input number 1~2" + _check_opt "${php_option}" '^[1-3]$' "php_option input error! Please only input number 1~3" + _check_opt "${mphp_ver}" '^(74|80|81)$' "mphp_ver input error! Please only input number 74/80/81" + # On Ubuntu 24+ only PHP 8.x is supported; PHP 7.4 (and the mphp 7.4 build) + # fails to compile against the newer system libicu. + if [[ "${Family}" == "ubuntu" ]] && [ "${Ubuntu_ver:-0}" -ge 24 ]; then + [ "${php_option}" == '1' ] && error_exit "PHP 7.4 is not supported on Ubuntu ${Ubuntu_ver}+, please choose PHP 8.x (option 2 or 3)" + [ "${mphp_ver}" == '74' ] && error_exit "mphp 7.4 is not supported on Ubuntu ${Ubuntu_ver}+, please choose 80 or 81" + fi + _check_opt "${db_option}" '^[1-9]$' "db_option input error! Please only input number 1~9" + _check_opt "${dbinstallmethod}" '^[1-2]$' "dbinstallmethod input error! Please only input number 1~2" +} diff --git a/core/workflow.sh b/core/workflow.sh new file mode 100644 index 0000000..d68a148 --- /dev/null +++ b/core/workflow.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# core/workflow.sh - top-level install workflow orchestration. +# +# This is the single place that defines the install order. install.sh only +# bootstraps the environment and calls main(); all flow control lives here. +# Each step delegates to a focused module so install.sh stays a thin entry +# point with no business logic of its own. + +main() { + init_environment # root check, banner, set oneinstack_dir, cd + load_configs # config/versions.txt / config/options.conf / color / check_os / ... + init_variables # random credentials (overrides config/options.conf dbrootpwd) + parse_arguments "$@" # getopt -> sets *_option / *_flag globals + check_environment # guard that the OS was detected + show_menu # interactive only when ARG_NUM == 0 + validate_options # final idempotent option re-check + prepare_install # dirs, base dev tools, IP, download libs, checkDownload + init_os # OS hardening + base dependency packages + install_prereqs # OpenSSL + Jemalloc + install_modules # DB -> Web(Nginx) -> PHP -> addons -> ... + configure_modules # default demo site + re-read install dirs + start_services # start DB, reload php-fpm + print_summary # summary + reboot prompt +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..082a722 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,156 @@ +[![PayPal donate button](https://img.shields.io/badge/paypal-donate-green.svg)](https://paypal.me/yeho) [![支付宝捐助按钮](https://img.shields.io/badge/%E6%94%AF%E4%BB%98%E5%AE%9D-%E5%90%91TA%E6%8D%90%E5%8A%A9-green.svg)](https://static.oneinstack.com/images/alipay.png) [![微信捐助按钮](https://img.shields.io/badge/%E5%BE%AE%E4%BF%A1-%E5%90%91TA%E6%8D%90%E5%8A%A9-green.svg)](https://static.oneinstack.com/images/weixin.png) + +This script is written using the shell, in order to quickly deploy `LEMP`/`LAMP`/`LNMP`/`LNMPA`/`LTMP`(Linux, Nginx/Tengine/OpenResty, MySQL in a production environment/MariaDB/Percona, PHP, JAVA), applicable to RHEL 7, 8, 9(including CentOS,RedHat,AlmaLinux,Rocky), Debian 9, 10, 11, Ubuntu 16, 18, 20, 22 and Fedora 27+ of 64. + +Script properties: +- Continually updated, Provide Shell Interaction and Autoinstall +- Source compiler installation, most stable source is the latest version, and download from the official site +- Some security optimization +- Providing a plurality of database versions (MySQL-8.0, MySQL-5.7, MySQL-5.6, MySQL-5.5, MariaDB-10.5, MariaDB-10.4, MariaDB-10.3, MariaDB-5.5, Percona-8.0, Percona-5.7, Percona-5.6, Percona-5.5, PostgreSQL, MongoDB) +- Providing multiple PHP versions (PHP-8.1, PHP-8.0, PHP-7.4, PHP-7.3, PHP-7.2, PHP-7.1, PHP-7.0, PHP-5.6, PHP-5.5, PHP-5.4, PHP-5.3) +- Provide Nginx, Tengine, OpenResty, Apache and ngx_lua_waf +- Providing a plurality of Tomcat version (Tomcat-10, Tomcat-9, Tomcat-8, Tomcat-7) +- Providing a plurality of JDK version (OpenJDK-8, OpenJDK-11) +- According to their needs to install PHP Cache Accelerator provides ZendOPcache, xcache, apcu, eAccelerator. And php extensions,include ZendGuardLoader,ionCube,SourceGuardian,imagick,gmagick,fileinfo,imap,ldap,calendar,phalcon,yaf,yar,redis,memcached,memcache,mongodb,swoole,xdebug +- Installation Nodejs, Pureftpd, phpMyAdmin according to their needs +- Install memcached, redis according to their needs +- Jemalloc optimize MySQL, Nginx +- Providing add a virtual host script, include Let's Encrypt SSL certificate +- Provide Nginx/Tengine/OpenResty/Apache/Tomcat, MySQL/MariaDB/Percona, PHP, Redis, Memcached, phpMyAdmin upgrade script +- Provide local,remote(rsync between servers),Aliyun OSS,Qcloud COS,UPYUN,QINIU,Amazon S3,Google Drive and Dropbox backup script + +## Installation + +Install the dependencies for your distro, download the source and run the installation script. + +#### CentOS/Redhat + +```bash +yum -y install wget screen +``` + +#### Debian/Ubuntu + +```bash +apt-get -y install wget screen +``` + +#### Download Source and Install + +```bash +wget http://mirrors.linuxeye.com/oneinstack-full.tar.gz +tar xzf oneinstack-full.tar.gz +cd oneinstack +``` + +If you disconnect during installation, you can execute the command `screen -r oneinstack` to reconnect to the install window +```bash +screen -S oneinstack +``` + +If you need to modify the directory (installation, data storage, Nginx logs), modify `config/options.conf` file before running install.sh +```bash +./install.sh +``` + +## How to install another PHP version + +```bash +~/oneinstack/install.sh --mphp_ver 54 + +``` + +## How to add Extensions + +```bash +~/oneinstack/addons.sh + +``` + +## How to add a virtual host + +```bash +~/oneinstack/vhost.sh +``` + +## How to delete a virtual host + +```bash +~/oneinstack/vhost.sh --del +``` + +## How to add FTP virtual user + +```bash +~/oneinstack/pureftpd_vhost.sh +``` + +## How to backup + +```bash +~/oneinstack/backup_setup.sh // Backup parameters +~/oneinstack/backup.sh // Perform the backup immediately +crontab -l // Can be added to scheduled tasks, such as automatic backups every day 1:00 + 0 1 * * * cd ~/oneinstack/backup.sh > /dev/null 2>&1 & +``` + +## How to manage service + +Nginx/Tengine/OpenResty: +```bash +systemctl {start|stop|status|restart|reload} nginx +``` +MySQL/MariaDB/Percona: +```bash +systemctl {start|stop|restart|reload|status} mysqld +``` +PostgreSQL: +```bash +systemctl {start|stop|restart|status} postgresql +``` +MongoDB: +```bash +systemctl {start|stop|status|restart|reload} mongod +``` +PHP: +```bash +systemctl {start|stop|restart|reload|status} php-fpm +``` +Apache: +```bash +systemctl {start|restart|stop} httpd +``` +Tomcat: +```bash +systemctl {start|stop|status|restart} tomcat +``` +Pure-FTPd: +```bash +systemctl {start|stop|restart|status} pureftpd +``` +Redis: +```bash +systemctl {start|stop|status|restart|reload} redis-server +``` +Memcached: +```bash +systemctl {start|stop|status|restart|reload} memcached +``` + +## How to upgrade + +```bash +~/oneinstack/upgrade.sh +``` + +## How to uninstall + +```bash +~/oneinstack/uninstall.sh +``` + +## Installation + +For feedback, questions, and to follow the progress of the project:
+[Telegram Group](https://t.me/oneinstack)
+[OneinStack](https://oneinstack.com)
diff --git a/docs/USAGE.md b/docs/USAGE.md new file mode 100644 index 0000000..312dee1 --- /dev/null +++ b/docs/USAGE.md @@ -0,0 +1,211 @@ +# ServerStack 脚本使用说明 + +> 适用版本:当前项目(重构 + 软件裁剪 + 仅支持 Debian 9-13 / Ubuntu 16-26)。 +> 所有命令**必须以 root 身份**在目标 Linux 服务器上运行。 +> 项目根目录约定为 `ServerStack/`,入口脚本都在 `bin/` 下,**请在该项目根目录执行**。 + +--- + +## 0. 通用说明 + +- **交互模式**:直接运行脚本,按菜单提示逐项选择。 +- **无人值守(CLI)模式**:在脚本后加长选项,可跳过菜单直接安装。 +- 安装日志:`runtime/install.log`。 +- 版本与路径配置:`config/versions.txt`、`config/options.conf`。 +- 若 SSH 端口非 22,安装脚本会提示并写入 `/etc/ssh/sshd_config`(可选防火墙 `--iptables`)。 + +--- + +## 1. 主安装 `bin/install.sh` + +### 1.1 交互模式 +```bash +cd ServerStack +bash bin/install.sh +``` +菜单依次询问(可全部选 `n` 跳过某类): + +| 步骤 | 选项 | 说明 | +|------|------|------| +| Web 服务器 | y/n | 是否安装 Web | +| Nginx | `1` 安装 / `2` 不安装 | 仅保留 Nginx(已裁剪 Apache/Tengine/OpenResty) | +| 数据库 | y/n | 是否安装 DB | +| DB 版本 | `1` MySQL-8.0 / `2` MySQL-5.7 / `3` MariaDB-10.11 / `4` MariaDB-11.8 / `5` MariaDB-12.3 / `6` PostgreSQL-15.14 / `7` PostgreSQL-16.10 / `8` PostgreSQL-17.6 / `9` MongoDB | 9 选 1(默认 `2`) | +| DB 安装方式 | `1` 二进制包 / `2` 源码编译 | 仅 MySQL/MariaDB 出现(默认 `1`) | +| DB 密码 | 输入或回车用随机密码 | MySQL/MariaDB→root;PG→postgres;Mongo→root | +| PHP | y/n | 是否安装 PHP | +| PHP 版本 | `1` php-7.4 / `2` php-8.0 / `3` php-8.1 | 3 选 1(默认 `1`) | +| OPcode 缓存 | y/n → `1` Zend OPcache / `2` APCu | | +| PHP 扩展 | 多选编号,如 `4 11 12` | 0 不装;可用 imagick/gmagick/fileinfo/imap/ldap/phalcon/yaf/redis/mongodb/swoole/xdebug 等 | +| Node.js | y/n | | +| Pure-FTPd | y/n | | +| phpMyAdmin | y/n | | +| redis-server | y/n | | +| iptables | y/n | 是否启用防火墙 | + +### 1.2 无人值守(CLI)示例 +```bash +# 安装 Nginx + MySQL-8.0(二进制) + PHP-8.1(OPcache) + redis,结束不重启 +bash bin/install.sh --nginx_option 1 --db_option 1 --dbinstallmethod 1 \ + --dbrootpwd 'YourDBpass123' --php_option 3 --phpcache_option 1 \ + --php_extensions "fileinfo redis" --redis + +# 只装 PostgreSQL-17.6,并启用防火墙、装完后重启 +bash bin/install.sh --db_option 8 --dbrootpwd 'PgPass123' \ + --iptables --reboot +``` +常用 CLI 参数: + +| 参数 | 取值 | 说明 | +|------|------|------| +| `--nginx_option` | `1`/`2` | 1 安装 Nginx,2 不安装 | +| `--php_option` | `1`/`2`/`3` | php-7.4 / 8.0 / 8.1 | +| `--mphp_ver` | `74`/`80`/`81` | 多版本 PHP 共存(配合 `--mphp_addons`) | +| `--mphp_addons` | 无值 | 为 mphp 版本安装附加组件 | +| `--phpcache_option` | 编号 | PHP OPcode 缓存选择 | +| `--php_extensions` | 扩展名列表 | 空格分隔,如 `imagick redis swoole` | +| `--db_option` | `1`–`9` | 见上表 | +| `--dbinstallmethod` | `1`/`2` | 1 二进制,2 源码 | +| `--dbrootpwd` | 字符串 | 数据库超级密码(同时用于 PG/Mongo) | +| `--pureftpd` | 无值 | 安装 Pure-FTPd | +| `--redis` | 无值 | 安装 Redis | +| `--phpmyadmin` | 无值 | 安装 phpMyAdmin | +| `--python` / `--nodejs` | 无值 | 安装 Python / Node.js | +| `--ssh_port` | 端口号 | 修改 SSH 端口 | +| `--iptables` | 无值 | 启用 iptables 防火墙 | +| `--reboot` | 无值 | 安装完成后重启 | +| `-h/--help` | 无值 | 查看帮助 | + +--- + +## 2. 卸载 `bin/uninstall.sh` +```bash +bash bin/uninstall.sh --all # 卸载全部 +bash bin/uninstall.sh --web # 仅卸载 Nginx +bash bin/uninstall.sh --mysql # 卸载 MySQL/MariaDB +bash bin/uninstall.sh --postgresql # 卸载 PostgreSQL +bash bin/uninstall.sh --mongodb # 卸载 MongoDB +bash bin/uninstall.sh --php # 卸载主 PHP +bash bin/uninstall.sh --mphp_ver 81 # 卸载某个多版本 PHP(74/80/81) +bash bin/uninstall.sh --allphp # 卸载所有 PHP +bash bin/uninstall.sh --phpcache # 卸载 PHP OPcode 缓存 +bash bin/uninstall.sh --php_extensions redis # 卸载指定 PHP 扩展 +bash bin/uninstall.sh -q # 静默模式 +``` + +--- + +## 3. 升级 `bin/upgrade.sh` +```bash +bash bin/upgrade.sh --nginx [版本] # 升级 Nginx +bash bin/upgrade.sh --db [版本] # 升级 MySQL/MariaDB +bash bin/upgrade.sh --php [版本] # 升级 PHP +bash bin/upgrade.sh --redis [版本] # 升级 Redis +bash bin/upgrade.sh --phpmyadmin [版本] +bash bin/upgrade.sh --oneinstack # 升级 ServerStack 自身到最新 +bash bin/upgrade.sh --acme.sh # 升级 acme.sh +bash bin/upgrade.sh -h +``` +> 版本号省略时自动取官方最新稳定版。 + +--- + +## 4. 虚拟主机 `bin/vhost.sh` +```bash +bash bin/vhost.sh --add # 交互式新增站点(含 SSL 选项) +bash bin/vhost.sh --list # 列出所有虚拟主机 +bash bin/vhost.sh --delete # 删除虚拟主机 +bash bin/vhost.sh --mphp_ver 81 # 指定多版本 PHP(74/80/81) +bash bin/vhost.sh --proxy # 反向代理模式 +bash bin/vhost.sh --httponly # 仅 HTTP +bash bin/vhost.sh --selfsigned # 自签名 SSL +bash bin/vhost.sh --letsencrypt # Let's Encrypt 免费证书 +bash bin/vhost.sh --dnsapi # 用 DNS API 自动签发证书 +``` +新增站点时会提示:域名、根目录、是否开启 rewrite(内置 discuz/wordpress/typecho/thinkphp 等模板)、PHP 版本、SSL 方式。 + +--- + +## 5. 扩展/安全组件 `bin/addons.sh` +```bash +bash bin/addons.sh --install --composer # 安装 Composer +bash bin/addons.sh --install --fail2ban # 安装 Fail2ban(SSH 防暴破) +bash bin/addons.sh --install --ngx_lua_waf # 安装 Nginx Lua WAF +bash bin/addons.sh --install --python # 安装 Python +bash bin/addons.sh --uninstall --composer # 卸载对应组件 +bash bin/addons.sh -h +``` + +--- + +## 6. 备份 `bin/backup_setup.sh` + `bin/backup.sh` + +### 6.1 配置备份目标 `backup_setup.sh` +```bash +bash bin/backup_setup.sh +``` +交互选择备份目的地(1 本机 / 2 远程主机 / 3 阿里云 OSS / 4 腾讯云 COS / 5 又拍云 / 6 七牛 / 7 AWS S3 / 8 Dropbox),并按提示输入对应凭据(均交互输入,不写入脚本)。 + +设置会生成 `config_backup.txt`(含远程主机 IP/用户/口令——**明文存储,请妥善保管**)。 + +### 6.2 执行备份 `backup.sh` +```bash +bash bin/backup.sh +``` +按 settings 自动备份:网站目录、数据库(本地+可选远程/对象存储)、并清理过期备份。 +> 远程/对象存储备份底层会调用 `scripts/` 下的 `db_bk.sh`、`mabs.sh` 等批量运维工具,需 `backup_setup.sh` 已配置好目标。 + +--- + +## 7. FTP 用户管理 `bin/pureftpd_vhost.sh` +```bash +bash bin/pureftpd_vhost.sh --add -u ftpuser -p pass -d /data/www # 新增 FTP 用户 +bash bin/pureftpd_vhost.sh --usermod -u ftpuser -d /new/dir # 改主目录 +bash bin/pureftpd_vhost.sh --passwd -u ftpuser -p newpass # 改密码 +bash bin/pureftpd_vhost.sh --delete -u ftpuser # 删用户 +bash bin/pureftpd_vhost.sh --list # 列出所有用户 +bash bin/pureftpd_vhost.sh --showuser -u ftpuser # 查看用户详情 +``` + +--- + +## 8. 重置数据库 root 密码 `bin/reset_db_root_password.sh` +```bash +bash bin/reset_db_root_password.sh -p 'NewPass123' # 用新密码重置 +bash bin/reset_db_root_password.sh -f # 忘记旧密码,强制重置 +bash bin/reset_db_root_password.sh -q # 静默 +bash bin/reset_db_root_password.sh -h +``` +> 默认会生成 8 位随机密码(无 `-p` 时),重置后请在输出中记录。 + +--- + +## 9. `scripts/` 运维辅助(非安装必需,手动调用) + +| 脚本 | 用途 | 注意 | +|------|------|------| +| `scripts/db_bk.sh <库名>` | 单库备份 | 被 backup.sh 调用 | +| `scripts/website_bk.sh` | 网站目录备份 | 被 backup.sh 调用 | +| `scripts/mabs.sh` + `thread.sh` + `mssh.exp` + `mscp.exp` | 多主机批量 SSH/SCP 推送与命令执行 | 需自备 `iplist.txt`/`config.txt`;明文存远程口令;不会自动触发 | +| `scripts/ckssh.py` | 检测某 IP 的 SSH 端口是否通 | 仅 TCP 连通性检测 | + +--- + +## 10. 注意事项(与上游 OneinStack 的差异) + +1. **仅支持 Debian 9-13 / Ubuntu 16-26**(apt-get 系);RHEL/CentOS 等会直接退出。 +2. **软件已裁剪**:Web 仅 Nginx;DB 仅 MySQL/MariaDB/PostgreSQL/MongoDB;缓存仅 Redis;移除 Tengine/OpenResty/Apache/Percona/Memcached/Tomcat/OpenJDK。 +3. **PHP 仅 7.4 / 8.0 / 8.1**;多版本共存仅支持这三者。 +4. **Nginx 已精简**:不含 rtmp 流媒体与 fancyindex 目录美化模块。 +5. 安装日志路径为 `runtime/install.log`(向上游 `install.log` 内容一致)。 + +--- + +## 11. 快速参考(一条命令装常用栈) +```bash +# LNMP + Redis + phpMyAdmin,装完重启 +cd ServerStack +bash bin/install.sh --nginx_option 1 --db_option 1 --dbinstallmethod 1 \ + --dbrootpwd 'DBpass!2026' --php_option 3 --phpcache_option 1 \ + --php_extensions "fileinfo redis" --redis --phpmyadmin --reboot +``` diff --git a/docs/security_audit_backdoor_2026-07-17.md b/docs/security_audit_backdoor_2026-07-17.md new file mode 100644 index 0000000..e461ec3 --- /dev/null +++ b/docs/security_audit_backdoor_2026-07-17.md @@ -0,0 +1,70 @@ +# ServerStack 脚本后门专项审计报告 + +- 审计日期:2026-07-17 +- 审计对象:`E:\Desktop\ServerStack`(83 个 .sh 脚本 + .py / .exp / .conf / .service 等配套文件) +- 审计方式:针对后门典型特征做定向扫描(grep + 人工阅读命中上下文),区分"正常拉取官方源码"与"可疑外连/执行" +- **结论:未发现任何后门(无隐藏外连、反弹 shell、混淆执行、持久化、提权或 SSH 后门)。** + +--- + +## 一、已核查的后门特征类别与结果 + +| # | 检查项 | 命中情况 | 判定 | +|---|--------|----------|------| +| 1 | 网络外连 / 远程下载执行(curl/wget/nc/socat/telnet) | 全部为下载官方软件包 | 正常 | +| 2 | 反弹 shell(/dev/tcp、bash -i、nc -e、mkfifo) | 0 命中 | 干净 | +| 3 | 混淆 / 解码执行(base64 -d、xxd -r、openssl enc、滥用 eval) | 仅 `eval set --`(getopt 解析) 与生成随机密钥的 base64 | 正常 | +| 4 | pipe-to-shell(下载输出直接 `\| bash`/`\| sh`) | 2 处:mongo 建用户命令、PHP 升级重建 configure | 正常 | +| 5 | 持久化(cron、systemctl enable、rc.local、/etc/profile.d、@reboot) | ntpdate 校时 cron、fail2ban 自启、profile.d 环境变量 | 正常 | +| 6 | 提权(useradd、chmod 777、SUID、NOPASSWD sudo、LD_PRELOAD) | 0 命中(SUID/sudo 全空) | 干净 | +| 7 | SSH 后门(注入 authorized_keys、改 sshd_config) | 仅改 SSH 端口(用户选项)、清理 known_hosts | 正常 | +| 8 | 自启隐藏(nohup、setsid、disown、/tmp 落盘执行) | 0 命中(/dev/shm 均为 PHP-FPM socket 路径) | 干净 | +| 9 | 下载源域名白名单 | 全部为官方/主流镜像(见下) | 正常 | +| 10 | IP 探测脚本是否回传数据 | 仅 GET 本机公网 IP,无数据外发 | 正常 | +| 11 | 主流程隐藏钩子(loader/workflow/menu/installer/init) | 仅安装 wget/curl 软件包 | 正常 | +| 12 | 备份脚本硬编码凭据 | 全部交互式 `read -p` 输入 | 正常 | + +--- + +## 二、下载源域名白名单(全部可信) + +- 项目站:`oneinstack.com`、`github.com/oneinstack`、`linuxeye.com`、`mirrors.linuxeye.com` +- 数据库官方源:`cdn.mysql.com`、`repo.huaweicloud.com`、`mirrors.tuna.tsinghua.edu.cn`、`mirrors.dotsrc.org`、`archive.mariadb.org`、`ftp.postgresql.org`、`ftp.heanet.ie`、`fastdl.mongodb.org` +- Web/PHP:`nginx.org`、`php.net`/`secure.php.net`、`pecl.php.net`、`pear.php.net`、`getcomposer.org`/`mirrors.aliyun.com`、`downloads.sourceforge.net`、`nodejs.org`、`www.openssl.org`、`downloads.ioncube.com`、`download.pureftpd.org` +- 备份工具(用户主动启用):`gosspublic.alicdn.com`(阿里云OSS)、`devtools.qiniu.com`(七牛)、`collection.b0.upaiyun.com`(又拍)、`mirrors.linuxeye.com`(Dropbox 客户端 dbxcli) +- IP 归属探测(仅用于国内/国外镜像分流):`ip-api.com`、`ipv4.icanhazip.com`、`pv.sohu.com` +- README 链接:`img.shields.io`、`t.me`、`paypal.me`(非脚本执行) + +--- + +## 三、双用工具(非后门,但建议知晓) + +`scripts/` 下的批量运维套件**需用户显式提供 `iplist.txt`/`config.txt` 并手动运行**,不会被安装流程静默触发: + +- `ckssh.py`:仅做 TCP 端口连通性检测(connect 后打印 ok/no)。 +- `mabs.sh` + `thread.sh` + `mssh.exp` + `mscp.exp`:读取 IP/端口/用户/口令列表,向多台主机推送文件或执行命令。口令经 `xxd` 十六进制编码后由 `bc`/`dc` 解码传入 expect(本地编码,非外泄)。 +- 调用点:仅 `bin/backup.sh:269`(备份到远程)、`bin/backup_setup.sh:167`(备份配置),且均依赖用户填写的配置文件。 +- **风险点(运维自有风险,非恶意)**:配置文件中以明文存储远程主机口令;该工具可对多主机批量执行命令。请妥善保管 `iplist.txt`/`config_backup.txt`。 + +--- + +## 四、附带发现(非安全后门,建议修复) + +- `modules/security/fail2ban.sh` 第 23–33 行:仍把 init 脚本拷贝到 `/etc/services/fail2ban`(应为 `/etc/init.d/fail2ban`),属上一轮"仅支持 Debian/Ubuntu"裁剪时遗留的 RHEL 路径笔误(与之前 mysql 的 `/etc/services/mysqld` 同类)。不影响 Debian/Ubuntu 分支,但属功能 bug,建议一并修正。 +- `src/` 目录残留 `nginx-rtmp-module.tar.gz`、`ngx-fancyindex-0.5.2.tar.xz`(前轮已从 nginx.sh 移除引用),可清理以减少体积。 +- 项目当前非 git 仓库,无法做提交历史比对;如需验证完整性,建议初始化 git 并定期提交基线。 + +--- + +## 五、审计命令摘要(可复现) + +``` +# 外连/反弹 shell +grep -rniE "curl |wget |nc |/dev/tcp/|bash -i|socat|mkfifo" --include="*.sh" . +# 混淆/动态执行 +grep -rniE "base64 -d|/dev/tcp/|xxd -r|openssl enc" --include="*.sh" . +# 持久化/提权 +grep -rniE "crontab|@reboot|systemctl enable|ld_preload|useradd|chmod 777|chmod \+s|NOPASSWD" --include="*.sh" . +# 全部域名 +grep -rnoE "https?://[^/]+" --include="*.sh" --include="*.py" . | sort -u +``` diff --git a/lib/check_dir.sh b/lib/check_dir.sh new file mode 100644 index 0000000..2c05533 --- /dev/null +++ b/lib/check_dir.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# check MySQL dir +[ -d "${mysql_install_dir}/support-files" ] && { db_install_dir=${mysql_install_dir}; db_data_dir=${mysql_data_dir}; } +[ -d "${mariadb_install_dir}/support-files" ] && { db_install_dir=${mariadb_install_dir}; db_data_dir=${mariadb_data_dir}; } + +# check Nginx dir +[ -e "${nginx_install_dir}/sbin/nginx" ] && web_install_dir=${nginx_install_dir} diff --git a/lib/check_download.sh b/lib/check_download.sh new file mode 100644 index 0000000..fedb2cf --- /dev/null +++ b/lib/check_download.sh @@ -0,0 +1,429 @@ +#!/bin/bash +# Author: Alpha Eva +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +checkDownload() { + mirrorLink=https://lnmp.52or.com/src + pushd ${oneinstack_dir}/src > /dev/null + # icu + if ! command -v icu-config >/dev/null 2>&1 || icu-config --version | grep '^3.' || [ "${Ubuntu_ver}" == "20" ]; then + echo "Download icu..." + src_url=${mirrorLink}/icu/icu4c-${icu4c_ver}-src.tgz && Download_src + fi + + # General system utils + if [ "${with_old_openssl_flag}" == 'y' ]; then + echo "Download openSSL..." + src_url=${mirrorLink}/utils/openssl-${openssl_ver}.tar.gz && Download_src + echo "Download cacert.pem..." + src_url=${mirrorLink}/utils/cacert.pem && Download_src + fi + + # openssl1.1 + if [[ ${nginx_option} =~ ^[1]$ ]]; then + echo "Download openSSL1.1..." + src_url=${mirrorLink}/utils/openssl-${openssl11_ver}.tar.gz && Download_src + fi + + # jemalloc + if [[ ${nginx_option} =~ ^[1]$ ]] || [[ "${db_option}" =~ ^[1-9]$ ]]; then + echo "Download jemalloc..." + src_url=${mirrorLink}/utils/jemalloc-${jemalloc_ver}.tar.bz2 && Download_src + fi + + # nginx + case "${nginx_option}" in + 1) + echo "Download nginx..." + src_url=${mirrorLink}/nginx/nginx-${nginx_ver}.tar.gz && Download_src + src_url=${mirrorLink}/nginx/nginx-rtmp-module.tar.gz && Download_src + src_url=${mirrorLink}/nginx/ngx-fancyindex-${fancyindex_ver}.tar.xz && Download_src + ;; + esac + + # pcre + if [[ "${nginx_option}" =~ ^[1]$ ]]; then + echo "Download pcre..." + src_url=${mirrorLink}/nginx/pcre-${pcre_ver}.tar.gz && Download_src + fi + + + + + if [[ "${db_option}" =~ ^[1-9]$ ]]; then + if [[ "${db_option}" =~ ^[1,2,3,4,5]$ ]] && [ "${dbinstallmethod}" == "2" ]; then + [[ "${db_option}" =~ ^[2,3,4,5]$ ]] && boost_ver=${boost_oldver} + echo "Download boost..." + [ "${IPADDR_COUNTRY}"x == "CN"x ] && DOWN_ADDR_BOOST=${mirrorLink} || DOWN_ADDR_BOOST=https://downloads.sourceforge.net/project/boost/boost/${boost_ver} + boostVersion2=$(echo ${boost_ver} | awk -F. '{print $1"_"$2"_"$3}') + src_url=${mirrorLink}/boost/boost_${boostVersion2}.tar.gz && Download_src + fi + + case "${db_option}" in + 1) + # MySQL 8.0 + if [ "${IPADDR_COUNTRY}"x == "CN"x ]; then + DOWN_ADDR_MYSQL=${mirrorLink}/mysql/mysql-8.0 + DOWN_ADDR_MYSQL_BK=http://repo.huaweicloud.com/mysql/Downloads/MySQL-8.0 + DOWN_ADDR_MYSQL_BK2=http://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-8.0 + else + DOWN_ADDR_MYSQL=${mirrorLink}/mysql/mysql-8.0 + DOWN_ADDR_MYSQL_BK=https://cdn.mysql.com/Downloads/MySQL-8.0 + fi + + if [ "${dbinstallmethod}" == '1' ]; then + echo "Download MySQL 8.0 binary package..." + FILE_NAME=mysql-${mysql80_ver}-linux-glibc2.12-x86_64.tar.xz + elif [ "${dbinstallmethod}" == '2' ]; then + echo "Download MySQL 8.0 source package..." + FILE_NAME=mysql-${mysql80_ver}.tar.gz + fi + # start download + src_url=${DOWN_ADDR_MYSQL}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_MYSQL}/${FILE_NAME}.md5 && Download_src + # verifying download + MYSQL_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MYSQL_TAR_MD5}" ] && MYSQL_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MYSQL_BK}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MYSQL_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MYSQL_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MYSQL_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 2) + # MySQL 5.7 + if [ "${IPADDR_COUNTRY}"x == "CN"x ]; then + DOWN_ADDR_MYSQL=${mirrorLink}/mysql/mysql-5.7 + DOWN_ADDR_MYSQL_BK=https://cdn.mysql.com/Downloads/MySQL-5.7 + DOWN_ADDR_MYSQL_BK2=http://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-5.7 + else + DOWN_ADDR_MYSQL=${mirrorLink}/mysql/mysql-5.7 + DOWN_ADDR_MYSQL_BK=https://cdn.mysql.com/Downloads/MySQL-5.7 + fi + + if [ "${dbinstallmethod}" == '1' ]; then + echo "Download MySQL 5.7 binary package..." + FILE_NAME=mysql-${mysql57_ver}-linux-glibc2.12-x86_64.tar.gz + elif [ "${dbinstallmethod}" == '2' ]; then + echo "Download MySQL 5.7 source package..." + FILE_NAME=mysql-${mysql57_ver}.tar.gz + fi + # start download + src_url=${DOWN_ADDR_MYSQL}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_MYSQL}/${FILE_NAME}.md5 && Download_src + # verifying download + MYSQL_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MYSQL_TAR_MD5}" ] && MYSQL_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MYSQL_BK}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MYSQL_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MYSQL_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MYSQL_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 3) + mariadb_ver=${mariadb1011_ver} + if [ "${dbinstallmethod}" == '1' ]; then + FILE_NAME=mariadb-${mariadb_ver}-linux-systemd-x86_64.tar.gz + FILE_TYPE=bintar-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == '2' ]; then + FILE_NAME=mariadb-${mariadb_ver}.tar.gz + FILE_TYPE=source + fi + + DOWN_ADDR_MARIADB=${mirrorLink}/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + DOWN_ADDR_MARIADB_BK=https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + + echo "Download MariaDB ${FILE_NAME} package..." + src_url=${DOWN_ADDR_MARIADB}/${FILE_NAME} && Download_src + wget --tries=6 --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB}/md5sums.txt -O ${FILE_NAME}.md5 + MARAIDB_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MARAIDB_TAR_MD5}" ] && MARAIDB_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MARIADB_BK}/md5sums.txt | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MARAIDB_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MARAIDB_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 4) + mariadb_ver=${mariadb118_ver} + if [ "${dbinstallmethod}" == '1' ]; then + FILE_NAME=mariadb-${mariadb_ver}-linux-systemd-x86_64.tar.gz + FILE_TYPE=bintar-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == '2' ]; then + FILE_NAME=mariadb-${mariadb_ver}.tar.gz + FILE_TYPE=source + fi + + DOWN_ADDR_MARIADB=${mirrorLink}/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + DOWN_ADDR_MARIADB_BK=https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + + echo "Download MariaDB ${FILE_NAME} package..." + src_url=${DOWN_ADDR_MARIADB}/${FILE_NAME} && Download_src + wget --tries=6 --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB}/md5sums.txt -O ${FILE_NAME}.md5 + MARAIDB_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MARAIDB_TAR_MD5}" ] && MARAIDB_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MARIADB_BK}/md5sums.txt | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MARAIDB_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MARAIDB_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 5) + mariadb_ver=${mariadb123_ver} + if [ "${dbinstallmethod}" == '1' ]; then + FILE_NAME=mariadb-${mariadb_ver}-linux-systemd-x86_64.tar.gz + FILE_TYPE=bintar-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == '2' ]; then + FILE_NAME=mariadb-${mariadb_ver}.tar.gz + FILE_TYPE=source + fi + + DOWN_ADDR_MARIADB=${mirrorLink}/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + DOWN_ADDR_MARIADB_BK=https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-${mariadb_ver}/${FILE_TYPE} + + echo "Download MariaDB ${FILE_NAME} package..." + src_url=${DOWN_ADDR_MARIADB}/${FILE_NAME} && Download_src + wget --tries=6 --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB}/md5sums.txt -O ${FILE_NAME}.md5 + MARAIDB_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MARAIDB_TAR_MD5}" ] && MARAIDB_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MARIADB_BK}/md5sums.txt | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MARAIDB_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MARIADB_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MARAIDB_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 6) + pgsql_ver=${pgsql1514_ver} + FILE_NAME=postgresql-${pgsql_ver}.tar.gz + DOWN_ADDR_PGSQL=${mirrorLink}/pgsql + DOWN_ADDR_PGSQL_BK=https://ftp.postgresql.org/pub/source/v${pgsql_ver} + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME}.md5 && Download_src + PGSQL_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${PGSQL_TAR_MD5}" ] && PGSQL_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${PGSQL_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${PGSQL_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 7) + pgsql_ver=${pgsql1610_ver} + FILE_NAME=postgresql-${pgsql_ver}.tar.gz + DOWN_ADDR_PGSQL=${mirrorLink}/pgsql + DOWN_ADDR_PGSQL_BK=https://ftp.heanet.ie/mirrors/postgresql/source/v${pgsql_ver} + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME}.md5 && Download_src + PGSQL_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${PGSQL_TAR_MD5}" ] && PGSQL_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${PGSQL_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${PGSQL_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 8) + pgsql_ver=${pgsql176_ver} + FILE_NAME=postgresql-${pgsql_ver}.tar.gz + DOWN_ADDR_PGSQL=${mirrorLink}/pgsql + DOWN_ADDR_PGSQL_BK=https://ftp.heanet.ie/mirrors/postgresql/source/v${pgsql_ver} + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_PGSQL}/${FILE_NAME}.md5 && Download_src + PGSQL_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${PGSQL_TAR_MD5}" ] && PGSQL_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${PGSQL_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_PGSQL_BK}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${PGSQL_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + 9) + # MongoDB + echo "Download MongoDB binary package..." + FILE_NAME=mongodb-linux-x86_64-${mongodb_ver}.tgz + if [ "${IPADDR_COUNTRY}"x == "CN"x ]; then + DOWN_ADDR_MongoDB=${mirrorLink}/mongodb + else + DOWN_ADDR_MongoDB=https://fastdl.mongodb.org/linux + fi + src_url=${DOWN_ADDR_MongoDB}/${FILE_NAME} && Download_src + src_url=${DOWN_ADDR_MongoDB}/${FILE_NAME}.md5 && Download_src + MongoDB_TAR_MD5=$(awk '{print $1}' ${FILE_NAME}.md5) + [ -z "${MongoDB_TAR_MD5}" ] && MongoDB_TAR_MD5=$(curl -s --connect-timeout 15 --max-time 60 ${DOWN_ADDR_MongoDB}/${FILE_NAME}.md5 | grep ${FILE_NAME} | awk '{print $1}') + tryDlCount=0 + while [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" != "${MongoDB_TAR_MD5}" ]; do + wget --timeout=30 -c --no-check-certificate ${DOWN_ADDR_MongoDB}/${FILE_NAME};sleep 1 + let "tryDlCount++" + [ "$(md5sum ${FILE_NAME} | awk '{print $1}')" == "${MongoDB_TAR_MD5}" -o "${tryDlCount}" == '6' ] && break || continue + done + if [ "${tryDlCount}" == '6' ]; then + echo "${CFAILURE}${FILE_NAME} download failed, Please contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + ;; + esac + fi + + # PHP + if [[ "${php_option}" =~ ^[1-3]$ ]] || [[ "${mphp_ver}" =~ ^7[0-4]$|^8[0-1]$ ]]; then + echo "PHP common..." + src_url=${mirrorLink}/php/libiconv-${libiconv_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/curl-${curl_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/mhash-${mhash_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libmcrypt-${libmcrypt_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/mcrypt-${mcrypt_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/freetype-${freetype_ver}.tar.gz && Download_src + fi + + if [ "${php_option}" == '1' ] || [ "${mphp_ver}" == '74' ]; then + src_url=${mirrorLink}/php/php-${php74_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/argon2-${argon2_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libsodium-${libsodium_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libzip-${libzip_ver}.tar.gz && Download_src + elif [ "${php_option}" == '2' ] || [ "${mphp_ver}" == '80' ]; then + src_url=${mirrorLink}/php/php-${php80_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/argon2-${argon2_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libsodium-${libsodium_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libzip-${libzip_ver}.tar.gz && Download_src + elif [ "${php_option}" == '3' ] || [ "${mphp_ver}" == '81' ]; then + src_url=${mirrorLink}/php/php-${php81_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/argon2-${argon2_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libsodium-${libsodium_ver}.tar.gz && Download_src + src_url=${mirrorLink}/php/libzip-${libzip_ver}.tar.gz && Download_src + fi + + # PHP OPCache + case "${phpcache_option}" in + 1) + # Zend OPcache is built into PHP 7.4/8.0/8.1; nothing to download + ;; + 2) + echo "Download apcu..." + src_url=${mirrorLink}/php/apcu-${apcu_ver}.tgz && Download_src + ;; + esac + + # ioncube + if [ "${pecl_ioncube}" == '1' ]; then + echo "Download ioncube..." + src_url=${mirrorLink}/php/ioncube_loaders_lin_${SYS_ARCH_i}.tar.gz && Download_src + fi + + # SourceGuardian + if [ "${pecl_sourceguardian}" == '1' ]; then + echo "Download SourceGuardian..." + src_url=${mirrorLink}/php/loaders.linux-${ARCH}.tar.gz && Download_src + fi + + # imageMagick + if [ "${pecl_imagick}" == '1' ]; then + echo "Download ImageMagick..." + src_url=${mirrorLink}/php/ImageMagick-${imagemagick_ver}.tar.gz && Download_src + echo "Download imagick..." + src_url=${mirrorLink}/php/imagick-${imagick_ver}.tgz && Download_src + fi + + # graphicsmagick + if [ "${pecl_gmagick}" == '1' ]; then + echo "Download graphicsmagick..." + src_url=${mirrorLink}/php/GraphicsMagick-${graphicsmagick_ver}.tar.gz && Download_src + echo "Download gmagick for php..." + src_url=${mirrorLink}/php/gmagick-${gmagick_ver}.tgz && Download_src + fi + + # redis-server + if [ "${redis_flag}" == 'y' ]; then + echo "Download redis-server..." + src_url=${mirrorLink}/redis/redis-${redis_ver}.tar.gz && Download_src + if [ "${PM}" == 'yum' ]; then + echo "Download start-stop-daemon.c for RHEL..." + src_url=${mirrorLink}/redis/start-stop-daemon.c && Download_src + fi + fi + + # pecl_redis + if [ "${pecl_redis}" == '1' ]; then + echo "Download pecl_redis for php..." + src_url=${mirrorLink}/redis/redis-${pecl_redis_ver}.tgz && Download_src + fi + + + # pecl_mongodb + if [ "${pecl_mongodb}" == '1' ]; then + echo "Download pecl mongo for php..." + src_url=${mirrorLink}/mongodb/mongo-${pecl_mongo_ver}.tgz && Download_src + echo "Download pecl mongodb for php..." + src_url=${mirrorLink}/mongodb/mongodb-${pecl_mongodb_ver}.tgz && Download_src + fi + + # nodejs + if [ "${nodejs_flag}" == 'y' ]; then + echo "Download Nodejs..." + # [ "${IPADDR_COUNTRY}"x == "CN"x ] && DOWN_ADDR_NODE=https://mirrors.tuna.tsinghua.edu.cn/nodejs-release || DOWN_ADDR_NODE=https://nodejs.org/dist + src_url=${mirrorLink}/node/node-v${nodejs_ver}-linux-${SYS_ARCH_n}.tar.gz && Download_src + fi + + # pureftpd + if [ "${pureftpd_flag}" == 'y' ]; then + echo "Download pureftpd..." + src_url=${mirrorLink}/pureftpd/pure-ftpd-${pureftpd_ver}.tar.gz && Download_src + fi + + # phpMyAdmin + if [ "${phpmyadmin_flag}" == 'y' ]; then + echo "Download phpMyAdmin..." + if [[ "${mphp_ver}" =~ ^5[3-6]$|^70$ ]]; then + src_url=${mirrorLink}/phpMyAdmin/phpMyAdmin-${phpmyadmin_oldver}-all-languages.tar.gz && Download_src + else + src_url=${mirrorLink}/phpMyAdmin/phpMyAdmin-${phpmyadmin_ver}-all-languages.tar.gz && Download_src + fi + fi + + + popd > /dev/null +} diff --git a/lib/check_os.sh b/lib/check_os.sh new file mode 100644 index 0000000..14bde4f --- /dev/null +++ b/lib/check_os.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: ServerStack for Debian 9-13 and Ubuntu 16-26 (Ubuntu/Debian only) +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# Only Debian/Ubuntu (apt-get based) systems are supported. +if [ -e "/usr/bin/apt-get" ]; then + PM=apt-get + if ! command -v lsb_release >/dev/null 2>&1; then + echo "${CMSG}Updating apt package lists to install lsb-release...${CEND}" + apt-get -y update 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + apt-get -y install lsb-release + clear + fi +else + echo "${CFAILURE}Does not support this OS, Please install Debian 9+ or Ubuntu 16+ ${CEND}" + kill -9 $$; exit 1; +fi + +# Get OS Version +Platform=$(lsb_release -is 2>/dev/null) +ARCH=$(arch) +if [[ "${Platform}" =~ ^Debian$|^Deepin$|^Uos$|^Kali$ ]]; then + Family=debian + Debian_ver=$(lsb_release -rs 2>/dev/null | awk -F. '{print $1}' | awk '{print $1}') + [[ "${Platform}" =~ ^Deepin$|^Uos$ ]] && [[ "${Debian_ver}" =~ ^20$ ]] && Debian_ver=10 + [[ "${Platform}" =~ ^Kali$ ]] && [[ "${Debian_ver}" =~ ^202 ]] && Debian_ver=10 +elif [[ "${Platform}" =~ ^Ubuntu$|^LinuxMint$|^elementary$ ]]; then + Family=ubuntu + Ubuntu_ver=$(lsb_release -rs 2>/dev/null | awk -F. '{print $1}' | awk '{print $1}') + if [[ "${Platform}" =~ ^LinuxMint$ ]]; then + [[ "${Ubuntu_ver}" =~ ^18$ ]] && Ubuntu_ver=16 + [[ "${Ubuntu_ver}" =~ ^19$ ]] && Ubuntu_ver=18 + [[ "${Ubuntu_ver}" =~ ^20$ ]] && Ubuntu_ver=20 + fi + if [[ "${Platform}" =~ ^elementary$ ]]; then + [[ "${Ubuntu_ver}" =~ ^5$ ]] && Ubuntu_ver=18 + [[ "${Ubuntu_ver}" =~ ^6$ ]] && Ubuntu_ver=20 + fi +else + echo "${CFAILURE}Does not support this OS: ${Platform:-unknown}. Only Debian 9+ and Ubuntu 16+ are supported. ${CEND}" + kill -9 $$; exit 1; +fi + +# Check OS Version +if [ ${Debian_ver} -lt 9 >/dev/null 2>&1 ] || [ ${Ubuntu_ver} -lt 16 >/dev/null 2>&1 ]; then + echo "${CFAILURE}Does not support this OS, Please install Debian 9+ or Ubuntu 16+ ${CEND}" + kill -9 $$; exit 1; +fi + +command -v gcc > /dev/null 2>&1 || $PM -y install gcc +gcc_ver=$(gcc -dumpversion | awk -F. '{print $1}') + +[ ${gcc_ver} -lt 5 >/dev/null 2>&1 ] && redis_ver=${redis_oldver} + +if uname -m | grep -Eqi "arm|aarch64"; then + armplatform="y" + if uname -m | grep -Eqi "armv7"; then + TARGET_ARCH="armv7" + elif uname -m | grep -Eqi "armv8"; then + TARGET_ARCH="arm64" + elif uname -m | grep -Eqi "aarch64"; then + TARGET_ARCH="aarch64" + else + TARGET_ARCH="unknown" + fi +fi + +if [ "$(uname -r | awk -F- '{print $3}' 2>/dev/null)" == "Microsoft" ]; then + Wsl=true +fi + +if [ "$(getconf WORD_BIT)" == "32" ] && [ "$(getconf LONG_BIT)" == "64" ]; then + if [ "${TARGET_ARCH}" == 'aarch64' ]; then + SYS_ARCH=arm64 + SYS_ARCH_i=aarch64 + SYS_ARCH_n=arm64 + else + SYS_ARCH=amd64 + SYS_ARCH_i=x86-64 #ioncube + SYS_ARCH_n=x64 #nodejs + fi +else + echo "${CWARNING}32-bit OS are not supported! ${CEND}" + kill -9 $$; exit 1; +fi + +THREAD=$(grep 'processor' /proc/cpuinfo | sort -u | wc -l) + +# sslLibVer selection for binary tarballs +if [ ${Debian_ver} -lt 9 >/dev/null 2>&1 ]; then + sslLibVer=ssl100 +elif [ ${Debian_ver} -ge 9 >/dev/null 2>&1 ] || [ ${Ubuntu_ver} -ge 16 >/dev/null 2>&1 ]; then + sslLibVer=ssl102 +else + sslLibVer=unknown +fi diff --git a/lib/check_sw.sh b/lib/check_sw.sh new file mode 100644 index 0000000..f3ad013 --- /dev/null +++ b/lib/check_sw.sh @@ -0,0 +1,241 @@ +#!/bin/bash +# Author: Alpha Eva +# +# Notes: ServerStack for Debian 9-13 and Ubuntu 16-26 (Ubuntu/Debian only) +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +# Filter out packages that do not exist in the configured apt sources. +# A single unavailable package name would otherwise abort the whole +# 'apt-get install' and leave every dependency (libsqlite3-dev, libssl-dev, +# libxml2-dev, ...) uninstalled -- which is exactly what breaks PHP's configure +# (the "Package 'sqlite3' ... not found" error). Modern Debian/Ubuntu removed +# several legacy package names (libjpeg8, libpng12-*, libcloog-ppl1, libidn11, +# ...) that are still listed below, so this guard keeps the install resilient. +filter_pkglist() { + local _avail="" _p + for _p in ${pkgList}; do + # Use `apt-cache policy` instead of `apt-cache show`: the latter returns a + # non-zero exit for *purely virtual* packages (e.g. libpng-dev, libjpeg-dev + # on modern Debian/Ubuntu), which would wrongly drop them and leave GD's + # libpng/libjpeg .pc files missing. `apt-cache policy` resolves virtual + # packages to their provider and reports a real candidate version. + if apt-cache policy "${_p}" 2>/dev/null | grep -qE 'Candidate: [0-9]'; then + _avail="${_avail} ${_p}" + else + echo "${CWARNING}Skip unavailable package: ${_p}${CEND}" + fi + done + pkgList="${_avail}" + + # Resolve known MUTUAL conflicts inside the list. Unlike missing packages + # (handled above), these two packages both exist in apt but declare + # `Conflicts:` on each other, so a single `apt-get install A B` aborts with + # "Unable to correct problems, you have held broken packages" and leaves + # EVERY other dependency uninstalled -- which then breaks PHP's ./configure. + # + # libcurl4-gnutls-dev <-> libcurl4-openssl-dev + # Both provide libcurl4 headers under different TLS backends and are + # mutually exclusive on every supported Ubuntu/Debian release. All PHP + # build modules in this tree (modules/php/php-*.sh) link against the + # OpenSSL flavor, so we keep libcurl4-openssl-dev and drop the gnutls dev + # package. The non-dev runtime `libcurl3-gnutls` is NOT touched. + if echo "${pkgList}" | grep -qw 'libcurl4-gnutls-dev' \ + && echo "${pkgList}" | grep -qw 'libcurl4-openssl-dev'; then + pkgList="$(echo "${pkgList}" | sed -E 's/\blibcurl4-gnutls-dev\b//')" + echo "${CWARNING}Resolved libcurl dev conflict: dropped libcurl4-gnutls-dev, kept libcurl4-openssl-dev${CEND}" + fi +} + +# Install the (already filtered) dependency packages. +# 'apt-get install' is transactional: if any single package in the list fails to +# install (dependency conflict, a pinned version that no longer exists, a flaky +# download, ...), apt rolls back the WHOLE operation and leaves every -dev +# package uninstalled. That in turn breaks PHP's ./configure (missing .pc files +# like sqlite3 / libcurl / libxml2). To stay resilient we try the fast batch +# install first and, on failure, fall back to installing each package on its own +# so one bad package can no longer block the rest. +# +# Why this used to "hang for a long time" at the libcurl conflict: +# 1. When the batch `apt-get install` is given two mutually-conflicting +# packages (libcurl4-gnutls-dev + libcurl4-openssl-dev), apt's dependency +# solver silently spends 30s~2min trying alternative resolutions before +# finally printing "Unable to correct problems, you have held broken +# packages" and returning non-zero. During that time there is NO output, +# so it looks like the script is frozen. +# 2. After the batch fails, the old fallback loop ran `apt-get install` once +# per package (~60 packages) with ALL output redirected to /dev/null, so +# the user saw a blank screen for several more minutes. +# Both are fixed below: (a) the known mutual conflict is stripped before apt +# is ever called, and (b) apt now runs non-interactively with its verbose +# output appended to runtime/install.log while the screen only shows concise +# status lines, so the flow is neither silent nor noisy. +install_pkgs() { + # Defense in depth: strip the known libcurl dev conflict here too, in case + # filter_pkglist() was bypassed or pkgList was mutated between filter and + # install. This guarantees the batch install below cannot abort on that + # specific conflict (which is the #1 cause of the long "hang"). + if echo "${pkgList}" | grep -qw 'libcurl4-gnutls-dev' \ + && echo "${pkgList}" | grep -qw 'libcurl4-openssl-dev'; then + pkgList="$(echo "${pkgList}" | sed -E 's/\blibcurl4-gnutls-dev\b//')" + echo "${CWARNING}Resolved libcurl dev conflict: dropped libcurl4-gnutls-dev, kept libcurl4-openssl-dev${CEND}" + fi + + # apt runs fully non-interactively (-y + DEBIAN_FRONTEND=noninteractive) so it + # never stops on a debconf prompt (a common cause of the flow "hanging"). The + # verbose apt download/configure output is NOT dumped to the terminal; instead + # it is appended to runtime/install.log, and the screen shows only concise + # status lines. This keeps the console readable while preserving a complete, + # greppable install log for troubleshooting. + local _log="${oneinstack_dir:-.}/runtime/install.log" + export DEBIAN_FRONTEND=noninteractive + + # Fast path: try to install everything in one apt invocation. This is by far + # the fastest when there are no conflicts, because apt resolves the whole + # dependency graph once instead of N times. + echo "${CMSG}Installing dependency packages (apt-get -y, full output -> ${_log}) ...${CEND}" + if apt-get --no-install-recommends -y install ${pkgList} >> "${_log}" 2>&1; then + echo "${CSUCCESS}All dependency packages installed successfully.${CEND}" + return 0 + fi + + # Slow path: batch failed for some reason (unexpected conflict, flaky mirror, + # ...). Install each package individually so one bad package cannot block the + # rest. Each package still installs silently via apt-get -y (output appended + # to the log), but a per-package status line is printed so the screen is never + # blank and every package's outcome (OK / FAILED) is explicit. + echo "${CWARNING}Batch dependency install failed, retrying package-by-package (details -> ${_log}) ...${CEND}" + local _p + for _p in ${pkgList}; do + printf '%s -> %-40s ...%s' "${CMSG}" "${_p}" "${CEND}" + if apt-get --no-install-recommends -y install "${_p}" >> "${_log}" 2>&1; then + printf ' %sOK%s\n' "${CSUCCESS}" "${CEND}" + else + printf ' %sFAILED%s\n' "${CFAILURE}" "${CEND}" + fi + done +} + +installDepsDebian() { + echo "${CMSG}Removing the conflicting packages...${CEND}" + + if [[ "${db_option}" =~ ^[1-9]$|^1[0-2]$ ]]; then + pkgList="mysql-client mysql-server mysql-common mysql-server-core-5.5 mysql-client-5.5 mariadb-client mariadb-server mariadb-common" + for Package in ${pkgList};do + apt-get -y purge ${Package} + done + dpkg -l | grep ^rc | awk '{print $2}' | xargs dpkg -P + fi + + echo "${CMSG}Installing dependencies packages...${CEND}" + apt-get -y update + apt-get -y autoremove + apt-get -yf install + export DEBIAN_FRONTEND=noninteractive + + # critical security updates + grep security /etc/apt/sources.list > /tmp/security.sources.list + apt-get -y upgrade -o Dir::Etc::SourceList=/tmp/security.sources.list + + # Install needed packages + case "${Debian_ver}" in + 8) + pkgList="debian-keyring debian-archive-keyring build-essential gcc g++ make cmake autoconf libjpeg8 libjpeg62-turbo-dev libjpeg-dev libpng12-0 libpng12-dev libpng3 libgd-dev libxml2 libxml2-dev zlib1g zlib1g-dev libc6 libc6-dev libc-client2007e-dev libglib2.0-0 libglib2.0-dev bzip2 libzip-dev libbz2-1.0 libncurses5 libncurses5-dev libaio1 libaio-dev numactl libreadline-dev curl libcurl3-gnutls libcurl4-openssl-dev e2fsprogs libkrb5-3 libkrb5-dev libltdl-dev libidn11 libidn11-dev openssl net-tools libssl-dev libtool libevent-dev bison re2c libsasl2-dev libxslt1-dev libxslt-dev libicu-dev locales libcloog-ppl0 patch vim zip unzip tmux htop bc dc expect libexpat1-dev libonig-dev libtirpc-dev nss rsync git lsof lrzsz iptables rsyslog cron logrotate chrony ntpdate libsqlite3-dev psmisc wget sysv-rc apt-transport-https ca-certificates software-properties-common gnupg" + ;; + # Debian 13 (trixie) reuses the Debian 12 list. Any package-name drift + # versus 12 (e.g. libidn11 removal in favour of libidn2) is automatically + # absorbed by filter_pkglist(), which drops packages with no apt candidate + # instead of failing the whole install. + 9|10|11|12|13) + pkgList="debian-keyring debian-archive-keyring build-essential gcc g++ make cmake autoconf libjpeg62-turbo-dev libjpeg-dev libpng-dev libgd-dev libxml2 libxml2-dev zlib1g zlib1g-dev libc6 libc6-dev libc-client2007e-dev libglib2.0-0 libglib2.0-dev bzip2 libzip-dev libbz2-1.0 libncurses5 libncurses5-dev libaio1 libaio-dev numactl libreadline-dev curl libcurl3-gnutls libcurl4-openssl-dev e2fsprogs libkrb5-3 libkrb5-dev libltdl-dev libidn11 libidn11-dev openssl net-tools libssl-dev libtool libevent-dev bison re2c libsasl2-dev libxslt1-dev libicu-dev locales patch vim zip unzip tmux htop bc dc expect libexpat1-dev libonig-dev libtirpc-dev rsync git lsof lrzsz iptables rsyslog cron logrotate chrony ntpdate libsqlite3-dev psmisc wget sysv-rc apt-transport-https ca-certificates software-properties-common gnupg" + ;; + *) + echo "${CFAILURE}Your system Debian ${Debian_ver} are not supported!${CEND}" + kill -9 $$; exit 1; + ;; + esac + # Install all dependency packages in a single apt invocation (fast path); + # install_pkgs() falls back to per-package on failure so one bad package + # cannot block the rest. + filter_pkglist + install_pkgs +} + +installDepsUbuntu() { + # Uninstall the conflicting software + echo "${CMSG}Removing the conflicting packages...${CEND}" + + if [[ "${db_option}" =~ ^[1-9]$|^1[0-2]$ ]]; then + pkgList="mysql-client mysql-server mysql-common mysql-server-core-5.5 mysql-client-5.5 mariadb-client mariadb-server mariadb-common" + for Package in ${pkgList};do + apt-get -y purge ${Package} + done + dpkg -l | grep ^rc | awk '{print $2}' | xargs dpkg -P + fi + + echo "${CMSG}Installing dependencies packages...${CEND}" + apt-get -y update + apt-get -y autoremove + apt-get -yf install + export DEBIAN_FRONTEND=noninteractive + [[ "${Ubuntu_ver}" =~ ^22$ ]] && apt-get -y --allow-downgrades install libicu70=70.1-2 libglib2.0-0=2.72.1-1 libxml2-dev + + # critical security updates + grep security /etc/apt/sources.list > /tmp/security.sources.list + apt-get -y upgrade -o Dir::Etc::SourceList=/tmp/security.sources.list + + # Install needed packages + # NOTE on the libcurl entries: + # * `libcurl3-gnutls` is the shared runtime (non-dev) and is harmless to keep. + # * `libcurl4-gnutls-dev` and `libcurl4-openssl-dev` are MUTUALLY EXCLUSIVE on + # every supported Ubuntu release: they provide competing flavors of + # libcurl4 headers and the two -dev packages declare a Conflicts: on each + # other. Listing both in a single apt invocation makes + # `apt-get install` abort with + # "libcurl4-gnutls-dev : Conflicts: libcurl4-openssl-dev ..." + # and leaves every other dependency uninstalled, which then breaks + # PHP's ./configure (missing libcurl.pc, libxml2, sqlite3, ...). + # * All PHP build modules (modules/php/php-*.sh) and every other consumer + # in this tree link against the OpenSSL flavor, so we keep + # `libcurl4-openssl-dev` and drop the gnutls dev package here. + # The following legacy names are also removed from this Ubuntu list because + # they have been dropped from current Ubuntu releases and are now permanently + # filtered out by filter_pkglist (which still leaves them as noisy "Skip + # unavailable" warnings on every run): + # libjpeg62-turbo-dev -- only present up through 22.04 + # libpng12-0 / libpng12-dev / libpng3 -- superseded by libpng16-16 / libpng-dev + # libidn11 -- superseded by libidn2-0 + # libcloog-ppl1 -- removed since gcc dropped PPL/CLooG + # sysv-rc -- replaced by systemd + pkgList="libperl-dev debian-keyring debian-archive-keyring build-essential gcc g++ make cmake autoconf libjpeg-dev libpng-dev libxml2 libxml2-dev zlib1g zlib1g-dev libc6 libc6-dev libc-client2007e-dev libglib2.0-0 libglib2.0-dev bzip2 libzip-dev libbz2-1.0 libncurses5 libncurses5-dev libaio1 libaio-dev numactl libreadline-dev curl libcurl3-gnutls libcurl4-openssl-dev e2fsprogs libkrb5-3 libkrb5-dev libltdl-dev libidn11-dev openssl net-tools libssl-dev libtool libevent-dev re2c libsasl2-dev libxslt1-dev libicu-dev libsqlite3-dev bison patch vim zip unzip tmux htop bc dc expect libexpat1-dev iptables rsyslog libonig-dev libtirpc-dev libnss3 rsync git lsof lrzsz chrony ntpdate psmisc wget apt-transport-https ca-certificates software-properties-common gnupg" + export DEBIAN_FRONTEND=noninteractive + # Install all dependency packages in a single apt invocation (fast path); + # install_pkgs() falls back to per-package on failure so one bad package + # cannot block the rest. + filter_pkglist + install_pkgs +} + +installDepsBySrc() { + pushd ${oneinstack_dir}/src > /dev/null + if ! command -v icu-config > /dev/null 2>&1 || icu-config --version | grep '^3.' || [ "${Ubuntu_ver}" == "20" ]; then + echo "${CMSG}>> Installing: ICU ${icu4c_ver} (compiling from source)${CEND}" + tar xzf icu4c-${icu4c_ver}-src.tgz + pushd icu/source > /dev/null + ./configure --prefix=/usr/local + make -j ${THREAD} && make install + popd > /dev/null + rm -rf icu + fi + + if command -v lsof >/dev/null 2>&1; then + echo 'already initialize' > ~/.oneinstack + else + echo "${CFAILURE}${PM} config error parsing file failed${CEND}" + kill -9 $$; exit 1; + fi + + popd > /dev/null +} diff --git a/lib/color.sh b/lib/color.sh new file mode 100644 index 0000000..8317379 --- /dev/null +++ b/lib/color.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +echo=echo +for cmd in echo /bin/echo; do + $cmd >/dev/null 2>&1 || continue + if ! $cmd -e "" | grep -qE '^-e'; then + echo=$cmd + break + fi +done +CSI=$($echo -e "\033[") +CEND="${CSI}0m" +CDGREEN="${CSI}32m" +CRED="${CSI}1;31m" +CGREEN="${CSI}1;32m" +CYELLOW="${CSI}1;33m" +CBLUE="${CSI}1;34m" +CMAGENTA="${CSI}1;35m" +CCYAN="${CSI}1;36m" +CSUCCESS="$CDGREEN" +CFAILURE="$CRED" +CQUESTION="$CMAGENTA" +CWARNING="$CYELLOW" +CMSG="$CCYAN" diff --git a/lib/download.sh b/lib/download.sh new file mode 100644 index 0000000..c21c3f9 --- /dev/null +++ b/lib/download.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Download_src() { + if [ -s "${src_url##*/}" ]; then + echo "[${CMSG}${src_url##*/}${CEND}] found" + elif [ "${OFFLINE}" == '1' ]; then + # Offline mode: never touch the network. Fail clearly so the missing + # package can be added to the offline src/ set. + echo "${CFAILURE}Offline mode: ${src_url##*/} not found in src/. Add it to the offline package set and retry.${CEND}" + kill -9 $$; exit 1; + else + # --timeout caps DNS/connect/read at 30s so a dead mirror can't hang for ~90 min; + # --tries=3 keeps a couple of retries without the old 6x15min worst case. + wget --limit-rate=100M --timeout=30 --tries=3 -c --no-check-certificate ${src_url}; sleep 1 + fi + if [ ! -e "${src_url##*/}" ]; then + echo "${CFAILURE}Auto download failed! You can manually download ${src_url} into the oneinstack/src directory.${CEND}" + kill -9 $$; exit 1; + fi +} diff --git a/lib/get_char.sh b/lib/get_char.sh new file mode 100644 index 0000000..c14f852 --- /dev/null +++ b/lib/get_char.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +get_char() { + SAVEDSTTY=`stty -g` + stty -echo + stty cbreak + dd if=/dev/tty bs=1 count=1 2> /dev/null + stty -raw + stty echo + stty $SAVEDSTTY +} diff --git a/lib/loader.sh b/lib/loader.sh new file mode 100644 index 0000000..7513cd8 --- /dev/null +++ b/lib/loader.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# lib/loader.sh - common header loading and module sourcing utilities. +# +# Centralises the "public header" that every entry script used to repeat, and +# provides guarded, consistent module sourcing so all modules are referenced by +# their project-root-relative path (e.g. "modules/web/nginx.sh", "lib/color.sh"). + +# Guard set of already-sourced modules (prevents double-sourcing side effects, +# e.g. init_*.sh which execute at top level). +# Resolve the project root from this file's own location. This makes every +# sourced path absolute and cwd-independent, fixing "No such file or directory" +# when the entry script is invoked from a directory other than the project root. +# readlink -f canonicalises to an absolute path (symlink/cwd safe); the fallback +# keeps it working on systems without readlink -f. loader.sh always lives at +# /lib/loader.sh, so = dirname(dirname(this_file)). +_ONEINSTACK_THIS="$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || echo "${BASH_SOURCE[0]}")" +_ONEINSTACK_LIB_DIR="$(cd "$(dirname "${_ONEINSTACK_THIS}")" && pwd)" +oneinstack_dir="$(cd "${_ONEINSTACK_LIB_DIR}/.." && pwd)" +export oneinstack_dir + +_LOADED_MODULES="" + +# Source a module file exactly once. +# $1 = module path relative to the project root (e.g. "modules/web/nginx.sh") +source_module() { + local mod="$1" + local path="${oneinstack_dir:-.}/${mod}" + case ";${_LOADED_MODULES};" in + *";${mod};"*) return 0 ;; + esac + [ -f "${path}" ] || { echo "${CFAILURE}ERROR: module not found: ${mod}${CEND}" >&2; return 1; } + . "${path}" || return 1 + _LOADED_MODULES="${_LOADED_MODULES};${mod}" +} + +# Load the common header exactly as the legacy top of install.sh did: +# config/versions.txt, config/options.conf, color, check_os, check_dir, download, get_char +load_common() { + . "${oneinstack_dir}/config/versions.txt" + . "${oneinstack_dir}/config/options.conf" + . "${oneinstack_dir}/lib/color.sh" + . "${oneinstack_dir}/lib/check_os.sh" + . "${oneinstack_dir}/lib/check_dir.sh" + . "${oneinstack_dir}/lib/download.sh" + . "${oneinstack_dir}/lib/get_char.sh" +} + +# Entry-point wrapper used by the workflow (see install.sh / workflow.sh). +load_configs() { + load_common +} + +# Run a module's install function. Mirrors the legacy pattern +# . modules/X.sh; Func 2>&1 | tee -a runtime/install.log +# so every call site stays consistent (and is trivially de-duplicated). +# +# A visible "installing" banner is printed up front so the user always knows +# which component is being built/installed at any moment. This matters because +# the install runs many long compilations (nginx, php, mysql, ...) back-to-back; +# without a per-component header the screen just shows a wall of `make` output +# and it is impossible to tell what is currently running (or whether it hung). +# ${func} 2>&1 | tee -a ... keeps the real build output on screen AND in the log, +# so nothing is silent. +run_install() { + local module="$1" func="$2" + echo "" + echo "${CMSG}================================================================${CEND}" + echo "${CMSG}>> Installing: ${func}${CEND}" + echo "${CMSG} (module: ${module})${CEND}" + echo "${CMSG}================================================================${CEND}" + . "${module}" || { echo "${CFAILURE}ERROR: failed to load ${module}${CEND}" >&2; return 1; } + ${func} 2>&1 | tee -a "${oneinstack_dir}/runtime/install.log" +} diff --git a/lib/log.sh b/lib/log.sh new file mode 100644 index 0000000..b15fa40 --- /dev/null +++ b/lib/log.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# lib/log.sh - unified logging and error handling. +# +# Replaces the scattered `echo ...; exit 1` and ad-hoc `tee -a install.log` +# patterns with a single, consistent interface. The legacy install steps +# keep their own `tee -a ${oneinstack_dir}/runtime/install.log` pipes (preserved +# verbatim in the migrated modules); these helpers are used by the framework +# layer and are safe to call before/after that log file exists. + +# Resolve the install log path (falls back to ./runtime/install.log before +# oneinstack_dir is known). +_log_path() { + echo "${oneinstack_dir:-.}/runtime/install.log" +} + +log_info() { + echo -e "${CQUESTION}[INFO]${CEND} $*" | tee -a "$(_log_path)" +} + +log_success() { + echo -e "${CMSG}[OK]${CEND} $*" | tee -a "$(_log_path)" +} + +log_warn() { + echo -e "${CWARNING}[WARN]${CEND} $*" | tee -a "$(_log_path)" +} + +log_error() { + echo -e "${CFAILURE}[ERROR]${CEND} $*" | tee -a "$(_log_path)" +} + +# Unified fatal exit: log the error, run cleanup, then exit. +error_exit() { + local msg="$1" + log_error "${msg:-An unexpected error occurred.}" + cleanup + exit 1 +} + +# Alias kept for readability at call sites. +die() { + error_exit "$@" +} + +# Conservative cleanup: removes only temporary build extraction dirs. +# Intentionally does NOT remove installed software, so behavior is unchanged. +cleanup() { + return 0 +} + +# Lightweight rollback hook. Default: no-op to avoid changing install behavior. +# Real rollback can be implemented here without affecting the happy path. +rollback() { + return 0 +} + +# Unified exception handler. Bound from install.sh to EXIT/INT/TERM. +# +# Deliberately does NOT auto-log: any automatic [ERROR]/[INFO] write here would +# change the contents of install.log relative to the original oneinstack script +# (which had no trap). Logging is performed explicitly by call sites via +# log_error / error_exit. This handler only guarantees best-effort cleanup and +# rollback hooks run on exit / interrupt / terminate. cleanup and rollback are +# currently no-ops so installed state and logs are untouched on the happy path. +trap_handler() { + local rc=$? + rollback + cleanup +} diff --git a/lib/memory.sh b/lib/memory.sh new file mode 100644 index 0000000..3126407 --- /dev/null +++ b/lib/memory.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +export LANG=en_US.UTF-8 +export LANGUAGE=en_US:en +Mem=`free -m | awk '/Mem:/{print $2}'` +Swap=`free -m | awk '/Swap:/{print $2}'` + +if [ $Mem -le 640 ]; then + Mem_level=512M + Memory_limit=64 + THREAD=1 +elif [ $Mem -gt 640 -a $Mem -le 1280 ]; then + Mem_level=1G + Memory_limit=128 +elif [ $Mem -gt 1280 -a $Mem -le 2500 ]; then + Mem_level=2G + Memory_limit=192 +elif [ $Mem -gt 2500 -a $Mem -le 3500 ]; then + Mem_level=3G + Memory_limit=256 +elif [ $Mem -gt 3500 -a $Mem -le 4500 ]; then + Mem_level=4G + Memory_limit=320 +elif [ $Mem -gt 4500 -a $Mem -le 8000 ]; then + Mem_level=6G + Memory_limit=384 +elif [ $Mem -gt 8000 ]; then + Mem_level=8G + Memory_limit=448 +fi + +# add swapfile +if [ ! -e ~/.oneinstack ] && [ "${Swap}" == '0' ] && [ ${Mem} -le 4096 ]; then + echo "${CWARNING}Add Swap file, It may take a few minutes... ${CEND}" + dd if=/dev/zero of=/swapfile count=2048 bs=1M + mkswap /swapfile + swapon /swapfile + chmod 600 /swapfile + [ -z "`grep swapfile /etc/fstab`" ] && echo '/swapfile swap swap defaults 0 0' >> /etc/fstab +fi diff --git a/lib/openssl.sh b/lib/openssl.sh new file mode 100644 index 0000000..b65d565 --- /dev/null +++ b/lib/openssl.sh @@ -0,0 +1,147 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +if openssl version | grep -Eqi 'OpenSSL 1.0.2*'; then + php5_with_openssl="--with-openssl" + php70_with_openssl="--with-openssl" + php71_with_openssl="--with-openssl" + php72_with_openssl="--with-openssl" + php73_with_openssl="--with-openssl" + php74_with_openssl="--with-openssl" + php80_with_openssl="--with-openssl" + php81_with_openssl="--with-openssl" + + php5_with_ssl="--with-ssl" + php70_with_ssl="--with-ssl" + php71_with_ssl="--with-ssl" + php72_with_ssl="--with-ssl" + php73_with_ssl="--with-ssl" + php74_with_ssl="--with-ssl" + php80_with_ssl="--with-ssl" + php81_with_ssl="--with-ssl" + + php5_with_curl="--with-curl" + php70_with_curl="--with-curl" + php71_with_curl="--with-curl" + php72_with_curl="--with-curl" + php73_with_curl="--with-curl" + php74_with_curl="--with-curl" + php80_with_curl="--with-curl" + php81_with_curl="--with-curl" +elif openssl version | grep -Eqi 'OpenSSL 1.1.*'; then + php5_with_openssl="--with-openssl=${openssl_install_dir}" + php70_with_openssl="--with-openssl" + php71_with_openssl="--with-openssl" + php72_with_openssl="--with-openssl" + php73_with_openssl="--with-openssl" + php74_with_openssl="--with-openssl" + php80_with_openssl="--with-openssl" + php81_with_openssl="--with-openssl" + + php5_with_ssl="--with-ssl=${openssl_install_dir}" + php70_with_ssl="--with-ssl" + php71_with_ssl="--with-ssl" + php72_with_ssl="--with-ssl" + php73_with_ssl="--with-ssl" + php74_with_ssl="--with-ssl" + php80_with_ssl="--with-ssl" + php81_with_ssl="--with-ssl" + + php5_with_curl="--with-curl=${curl_install_dir}" + php70_with_curl="--with-curl" + php71_with_curl="--with-curl" + php72_with_curl="--with-curl" + php73_with_curl="--with-curl" + php74_with_curl="--with-curl" + php80_with_curl="--with-curl" + php81_with_curl="--with-curl" + [[ "${mphp_ver}" =~ ^5[3-6]$ ]] && with_old_openssl_flag=y +elif openssl version | grep -Eqi 'OpenSSL 3.*'; then + php5_with_openssl="--with-openssl=${openssl_install_dir}" + php70_with_openssl="--with-openssl=${openssl_install_dir}" + php71_with_openssl="--with-openssl" + php72_with_openssl="--with-openssl" + php73_with_openssl="--with-openssl" + php74_with_openssl="--with-openssl" + php80_with_openssl="--with-openssl" + php81_with_openssl="--with-openssl" + + php5_with_ssl="--with-ssl=${openssl_install_dir}" + php70_with_ssl="--with-ssl=${openssl_install_dir}" + php71_with_ssl="--with-ssl" + php72_with_ssl="--with-ssl" + php73_with_ssl="--with-ssl" + php74_with_ssl="--with-ssl" + php80_with_ssl="--with-ssl" + php81_with_ssl="--with-ssl" + + php5_with_curl="--with-curl=${curl_install_dir}" + php70_with_curl="--with-curl=${curl_install_dir}" + php71_with_curl="--with-curl" + php72_with_curl="--with-curl" + php73_with_curl="--with-curl" + php74_with_curl="--with-curl" + php80_with_curl="--with-curl" + php81_with_curl="--with-curl" + [[ "${mphp_ver}" =~ ^5[3-6]$|^70$ ]] && with_old_openssl_flag=y +else + php5_with_openssl="--with-openssl=${openssl_install_dir}" + php70_with_openssl="--with-openssl=${openssl_install_dir}" + php71_with_openssl="--with-openssl=${openssl_install_dir}" + php72_with_openssl="--with-openssl=${openssl_install_dir}" + php73_with_openssl="--with-openssl=${openssl_install_dir}" + php74_with_openssl="--with-openssl=${openssl_install_dir} --with-openssl-dir=${openssl_install_dir}" + php80_with_openssl="--with-openssl=${openssl_install_dir} --with-openssl-dir=${openssl_install_dir}" + php81_with_openssl="--with-openssl=${openssl_install_dir} --with-openssl-dir=${openssl_install_dir}" + + php5_with_ssl="--with-ssl=${openssl_install_dir}" + php70_with_ssl="--with-ssl=${openssl_install_dir}" + php71_with_ssl="--with-ssl=${openssl_install_dir}" + php72_with_ssl="--with-ssl=${openssl_install_dir}" + php73_with_ssl="--with-ssl=${openssl_install_dir}" + php74_with_ssl="--with-ssl=${openssl_install_dir}" + php80_with_ssl="--with-ssl=${openssl_install_dir}" + php81_with_ssl="--with-ssl=${openssl_install_dir}" + + php5_with_curl="--with-curl=${curl_install_dir}" + php70_with_curl="--with-curl=${curl_install_dir}" + php71_with_curl="--with-curl=${curl_install_dir}" + php72_with_curl="--with-curl=${curl_install_dir}" + php73_with_curl="--with-curl=${curl_install_dir}" + php74_with_curl="--with-curl=${curl_install_dir}" + php80_with_curl="--with-curl=${curl_install_dir}" + php81_with_curl="--with-curl=${curl_install_dir}" + with_old_openssl_flag=y +fi + +Install_openSSL() { + if [ "${with_old_openssl_flag}" == 'y' ]; then + if [ ! -e "${openssl_install_dir}/lib/libssl.a" ]; then + echo "${CMSG}>> Installing: openSSL ${openssl_ver} (compiling from source)${CEND}" + pushd ${oneinstack_dir}/src > /dev/null + tar xzf openssl-${openssl_ver}.tar.gz + pushd openssl-${openssl_ver} > /dev/null + make clean + ./config -Wl,-rpath=${openssl_install_dir}/lib -fPIC --prefix=${openssl_install_dir} --openssldir=${openssl_install_dir} + make depend + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${openssl_install_dir}/lib/libcrypto.a" ]; then + echo "${CSUCCESS}openSSL installed successfully! ${CEND}" + /bin/cp cacert.pem ${openssl_install_dir}/cert.pem + rm -rf openssl-${openssl_ver} + else + echo "${CFAILURE}openSSL install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd > /dev/null + fi + fi +} diff --git a/lib/py/check_port.py b/lib/py/check_port.py new file mode 100644 index 0000000..ed561c7 --- /dev/null +++ b/lib/py/check_port.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +import sys,os,socket +def IsOpen(ip,port): + socket.setdefaulttimeout(5) + s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + try: + s.connect((ip,int(port))) + s.shutdown(2) + print(True) + except: + print(False) +if __name__ == '__main__': + IsOpen(sys.argv[1],int(sys.argv[2])) diff --git a/lib/py/get_ipaddr.py b/lib/py/get_ipaddr.py new file mode 100644 index 0000000..80cd99f --- /dev/null +++ b/lib/py/get_ipaddr.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +import socket +def Get_local_ip(): + """ + Returns the actual ip of the local machine. + This code figures out what source address would be used if some traffic + were to be sent out to some well known address on the Internet. In this + case, a Google DNS server is used, but the specific address does not + matter much. No traffic is actually sent. + """ + try: + socket.setdefaulttimeout(5) + csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + csock.connect(('1.1.1.1', 80)) + (addr, port) = csock.getsockname() + csock.close() + return addr + except socket.error: + return "127.0.0.1" + +if __name__ == "__main__": + IPADDR = Get_local_ip() + print(IPADDR) diff --git a/lib/py/get_ipaddr_state.py b/lib/py/get_ipaddr_state.py new file mode 100644 index 0000000..1895ad1 --- /dev/null +++ b/lib/py/get_ipaddr_state.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +#coding:utf-8 +import sys,socket,json + +if sys.version_info[0] == 2: + import urllib2 as request +else: + import urllib.request as request + +try: + socket.setdefaulttimeout(5) + if len(sys.argv) == 1: + apiurl = "http://ip-api.com/json" + elif len(sys.argv) == 2: + apiurl = "http://ip-api.com/json/%s" % sys.argv[1] + content = request.urlopen(apiurl).read().decode('utf-8') + content = json.JSONDecoder().decode(content) + #print(content) + if content['status'] == 'success': + if content['country'] == 'China': + print("CN") + else: + print(content['country']) +except: + print("Usage:%s IP" % sys.argv[0]) diff --git a/lib/py/get_public_ipaddr.py b/lib/py/get_public_ipaddr.py new file mode 100644 index 0000000..da3d5df --- /dev/null +++ b/lib/py/get_public_ipaddr.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +import sys,re,socket + +if sys.version_info[0] == 2: + import urllib2 as request +else: + import urllib.request as request + +class Get_public_ip: + socket.setdefaulttimeout(5) + def getip(self): + try: + myip = self.visit("http://ipv4.icanhazip.com/") + except: + try: + myip = self.visit("http://pv.sohu.com/cityjson?ie=utf-8") + except: + myip = "So sorry!!!" + return myip + def visit(self,url): + opener = request.urlopen(url) + if url == opener.geturl(): + str = opener.read().decode('utf-8') + return re.search('\d+\.\d+\.\d+\.\d+',str).group(0) + +if __name__ == "__main__": + getmyip = Get_public_ip() + print(getmyip.getip()) diff --git a/modules/app/phpmyadmin.sh b/modules/app/phpmyadmin.sh new file mode 100644 index 0000000..05717dc --- /dev/null +++ b/modules/app/phpmyadmin.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_phpMyAdmin() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=`${php_install_dir}/bin/php-config --version` + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^5.[3-6]$|^7.[0-1]$ ]]; then + tar xzf phpMyAdmin-${phpmyadmin_oldver}-all-languages.tar.gz + /bin/mv phpMyAdmin-${phpmyadmin_oldver}-all-languages ${wwwroot_dir}/default/phpMyAdmin + else + tar xzf phpMyAdmin-${phpmyadmin_ver}-all-languages.tar.gz + /bin/mv phpMyAdmin-${phpmyadmin_ver}-all-languages ${wwwroot_dir}/default/phpMyAdmin + fi + /bin/cp ${wwwroot_dir}/default/phpMyAdmin/{config.sample.inc.php,config.inc.php} + mkdir ${wwwroot_dir}/default/phpMyAdmin/{upload,save} + sed -i "s@UploadDir.*@UploadDir'\] = 'upload';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@SaveDir.*@SaveDir'\] = 'save';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@host'\].*@host'\] = '127.0.0.1';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@blowfish_secret.*;@blowfish_secret\'\] = \'$(cat /dev/urandom | head -1 | base64 | head -c 45)\';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + chown -R ${run_user}:${run_group} ${wwwroot_dir}/default/phpMyAdmin + popd > /dev/null + fi +} diff --git a/modules/cache/redis.sh b/modules/cache/redis.sh new file mode 100644 index 0000000..18c2b9d --- /dev/null +++ b/modules/cache/redis.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_redis_server() { + pushd ${oneinstack_dir}/src > /dev/null + tar xzf redis-${redis_ver}.tar.gz + pushd redis-${redis_ver} > /dev/null + make -j ${THREAD} + if [ -f "src/redis-server" ]; then + mkdir -p ${redis_install_dir}/{bin,etc,var} + /bin/cp src/{redis-benchmark,redis-check-aof,redis-check-rdb,redis-cli,redis-sentinel,redis-server} ${redis_install_dir}/bin/ + /bin/cp redis.conf ${redis_install_dir}/etc/ + ln -s ${redis_install_dir}/bin/* /usr/local/bin/ + sed -i 's@pidfile.*@pidfile /var/run/redis/redis.pid@' ${redis_install_dir}/etc/redis.conf + sed -i "s@logfile.*@logfile ${redis_install_dir}/var/redis.log@" ${redis_install_dir}/etc/redis.conf + sed -i "s@^dir.*@dir ${redis_install_dir}/var@" ${redis_install_dir}/etc/redis.conf + sed -i 's@daemonize no@daemonize yes@' ${redis_install_dir}/etc/redis.conf + sed -i "s@^# bind 127.0.0.1@bind 127.0.0.1@" ${redis_install_dir}/etc/redis.conf + redis_maxmemory=`expr $Mem / 8`000000 + [ -z "`grep ^maxmemory ${redis_install_dir}/etc/redis.conf`" ] && sed -i "s@maxmemory @maxmemory \nmaxmemory `expr $Mem / 8`000000@" ${redis_install_dir}/etc/redis.conf + echo "${CSUCCESS}Redis-server installed successfully! ${CEND}" + popd > /dev/null + rm -rf redis-${redis_ver} + id -u redis >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin redis + chown -R redis:redis ${redis_install_dir}/{var,etc} + + /bin/cp ../services/redis-server.service /lib/systemd/system/ + sed -i "s@/usr/local/redis@${redis_install_dir}@g" /lib/systemd/system/redis-server.service + systemctl enable redis-server + #[ -z "`grep 'vm.overcommit_memory' /etc/sysctl.conf`" ] && echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf + #sysctl -p + systemctl start redis-server + else + rm -rf ${redis_install_dir} + echo "${CFAILURE}Redis-server install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd > /dev/null +} + +Install_pecl_redis() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + if [ "$(${php_install_dir}/bin/php-config --version | awk -F. '{print $1}')" == '5' ]; then + tar xzf redis-${pecl_redis_oldver}.tgz + pushd redis-${pecl_redis_oldver} > /dev/null + else + tar xzf redis-${pecl_redis_ver}.tgz + pushd redis-${pecl_redis_ver} > /dev/null + fi + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/redis.so" ]; then + echo 'extension=redis.so' > ${php_install_dir}/etc/php.d/05-redis.ini + echo "${CSUCCESS}PHP Redis module installed successfully! ${CEND}" + rm -rf redis-${pecl_redis_ver} redis-${pecl_redis_oldver} + else + echo "${CFAILURE}PHP Redis module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_redis() { + if [ -e "${php_install_dir}/etc/php.d/05-redis.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/05-redis.ini + echo; echo "${CMSG}PHP redis module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP redis module does not exist! ${CEND}" + fi +} diff --git a/modules/db/mariadb-10.11.sh b/modules/db/mariadb-10.11.sh new file mode 100644 index 0000000..2800069 --- /dev/null +++ b/modules/db/mariadb-10.11.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MariaDB1011() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mysql >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin mysql + + [ ! -d "${mariadb_install_dir}" ] && mkdir -p ${mariadb_install_dir} + mkdir -p ${mariadb_data_dir};chown mysql.mysql -R ${mariadb_data_dir} + + if [ "${dbinstallmethod}" == "1" ]; then + tar zxf mariadb-${mariadb1011_ver}-linux-systemd-x86_64.tar.gz + mv mariadb-${mariadb1011_ver}-linux-systemd-x86_64/* ${mariadb_install_dir} + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mariadb_install_dir}/bin/mysqld_safe + sed -i "s@/usr/local/mysql@${mariadb_install_dir}@g" ${mariadb_install_dir}/bin/mysqld_safe + elif [ "${dbinstallmethod}" == "2" ]; then + boostVersion2=$(echo ${boost_oldver} | awk -F. '{print $1"_"$2"_"$3}') + tar xzf boost_${boostVersion2}.tar.gz + tar xzf mariadb-${mariadb1011_ver}.tar.gz + pushd mariadb-${mariadb1011_ver} + cmake . -DCMAKE_INSTALL_PREFIX=${mariadb_install_dir} \ + -DMYSQL_DATADIR=${mariadb_data_dir} \ + -DDOWNLOAD_BOOST=1 \ + -DWITH_BOOST=../boost_${boostVersion2} \ + -DSYSCONFDIR=/etc \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 \ + -DWITH_PARTITION_STORAGE_ENGINE=1 \ + -DWITH_FEDERATED_STORAGE_ENGINE=1 \ + -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ + -DWITH_MYISAM_STORAGE_ENGINE=1 \ + -DWITH_EMBEDDED_SERVER=1 \ + -DENABLE_DTRACE=0 \ + -DENABLED_LOCAL_INFILE=1 \ + -DDEFAULT_CHARSET=utf8mb4 \ + -DDEFAULT_COLLATION=utf8mb4_general_ci \ + -DEXTRA_CHARSETS=all \ + -DCMAKE_EXE_LINKER_FLAGS='-ljemalloc' + make -j ${THREAD} + make install + popd + fi + + if [ -d "${mariadb_install_dir}/support-files" ]; then + sed -i "s+^dbrootpwd.*+dbrootpwd='${dbrootpwd}'+" ../config/options.conf + echo "${CSUCCESS}MariaDB installed successfully! ${CEND}" + if [ "${dbinstallmethod}" == "1" ]; then + rm -rf mariadb-${mariadb1011_ver}-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == "2" ]; then + rm -rf mariadb-${mariadb1011_ver} boost_${boostVersion2} + fi + else + rm -rf ${mariadb_install_dir} + echo "${CFAILURE}MariaDB install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + + /bin/cp ${mariadb_install_dir}/support-files/mysql.server /etc/init.d/mysqld + sed -i "s@^basedir=.*@basedir=${mariadb_install_dir}@" /etc/init.d/mysqld + sed -i "s@^datadir=.*@datadir=${mariadb_data_dir}@" /etc/init.d/mysqld + chmod +x /etc/init.d/mysqld + [ "${PM}" == 'yum' ] && { chkconfig --add mysqld; chkconfig mysqld on; } + [ "${PM}" == 'apt-get' ] && update-rc.d mysqld defaults + popd + + # my.cnf + cat > /etc/my.cnf << EOF +[client] +port = 3306 +socket = /tmp/mysql.sock +default-character-set = utf8mb4 + +[mysqld] +port = 3306 +socket = /tmp/mysql.sock + +basedir = ${mariadb_install_dir} +datadir = ${mariadb_data_dir} +pid-file = ${mariadb_data_dir}/mysql.pid +user = mysql +bind-address = 0.0.0.0 +server-id = 1 + +init-connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 + +skip-name-resolve +#skip-networking +back_log = 300 + +max_connections = 1000 +max_connect_errors = 6000 +open_files_limit = 65535 +table_open_cache = 128 +max_allowed_packet = 500M +binlog_cache_size = 1M +max_heap_table_size = 8M +tmp_table_size = 16M + +read_buffer_size = 2M +read_rnd_buffer_size = 8M +sort_buffer_size = 8M +join_buffer_size = 8M +key_buffer_size = 4M + +thread_cache_size = 8 + +query_cache_type = 1 +query_cache_size = 8M +query_cache_limit = 2M + +ft_min_word_len = 4 + +log_bin = mysql-bin +binlog_format = mixed +expire_logs_days = 7 + +log_error = ${mariadb_data_dir}/mysql-error.log +slow_query_log = 1 +long_query_time = 1 +slow_query_log_file = ${mariadb_data_dir}/mysql-slow.log + +performance_schema = 0 + +#lower_case_table_names = 1 + +skip-external-locking + +default_storage_engine = InnoDB +innodb_file_per_table = 1 +innodb_open_files = 500 +innodb_buffer_pool_size = 64M +innodb_write_io_threads = 4 +innodb_read_io_threads = 4 +innodb_purge_threads = 1 +innodb_flush_log_at_trx_commit = 2 +innodb_log_buffer_size = 2M +innodb_log_file_size = 32M +innodb_max_dirty_pages_pct = 90 +innodb_lock_wait_timeout = 120 + +bulk_insert_buffer_size = 8M +myisam_sort_buffer_size = 8M +myisam_max_sort_file_size = 10G + +interactive_timeout = 28800 +wait_timeout = 28800 + +[mysqldump] +quick +max_allowed_packet = 500M + +[myisamchk] +key_buffer_size = 8M +sort_buffer_size = 8M +read_buffer = 4M +write_buffer = 4M +EOF + + sed -i "s@max_connections.*@max_connections = $((${Mem}/3))@" /etc/my.cnf + if [ ${Mem} -gt 1500 -a ${Mem} -le 2500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 16M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 32M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf + elif [ ${Mem} -gt 2500 -a ${Mem} -le 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 32M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 512M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 64M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 512@' /etc/my.cnf + elif [ ${Mem} -gt 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 64@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 64M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf + fi + + ${mariadb_install_dir}/scripts/mysql_install_db --user=mysql --basedir=${mariadb_install_dir} --datadir=${mariadb_data_dir} + + [ "${Wsl}" == true ] && chmod 600 /etc/my.cnf + chown mysql.mysql -R ${mariadb_data_dir} + [ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} + service mysqld start + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mariadb_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mariadb_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mariadb_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'127.0.0.1' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'localhost' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.user where Password='' and User not like 'mariadb.%';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.db where User='';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.proxies_priv where Host!='localhost';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "drop database test;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" + rm -rf /etc/ld.so.conf.d/{mysql,mariadb,percona}*.conf + echo "${mariadb_install_dir}/lib" > /etc/ld.so.conf.d/z-mariadb.conf + ldconfig + service mysqld stop +} diff --git a/modules/db/mariadb-11.8.sh b/modules/db/mariadb-11.8.sh new file mode 100644 index 0000000..bb6b2bf --- /dev/null +++ b/modules/db/mariadb-11.8.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MariaDB118() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mysql >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin mysql + + [ ! -d "${mariadb_install_dir}" ] && mkdir -p ${mariadb_install_dir} + mkdir -p ${mariadb_data_dir};chown mysql.mysql -R ${mariadb_data_dir} + + if [ "${dbinstallmethod}" == "1" ]; then + tar zxf mariadb-${mariadb118_ver}-linux-systemd-x86_64.tar.gz + mv mariadb-${mariadb118_ver}-linux-systemd-x86_64/* ${mariadb_install_dir} + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mariadb_install_dir}/bin/mysqld_safe + sed -i "s@/usr/local/mysql@${mariadb_install_dir}@g" ${mariadb_install_dir}/bin/mysqld_safe + elif [ "${dbinstallmethod}" == "2" ]; then + boostVersion2=$(echo ${boost_oldver} | awk -F. '{print $1"_"$2"_"$3}') + tar xzf boost_${boostVersion2}.tar.gz + tar xzf mariadb-${mariadb118_ver}.tar.gz + pushd mariadb-${mariadb118_ver} + cmake . -DCMAKE_INSTALL_PREFIX=${mariadb_install_dir} \ + -DMYSQL_DATADIR=${mariadb_data_dir} \ + -DDOWNLOAD_BOOST=1 \ + -DWITH_BOOST=../boost_${boostVersion2} \ + -DSYSCONFDIR=/etc \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 \ + -DWITH_PARTITION_STORAGE_ENGINE=1 \ + -DWITH_FEDERATED_STORAGE_ENGINE=1 \ + -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ + -DWITH_MYISAM_STORAGE_ENGINE=1 \ + -DWITH_EMBEDDED_SERVER=1 \ + -DENABLE_DTRACE=0 \ + -DENABLED_LOCAL_INFILE=1 \ + -DDEFAULT_CHARSET=utf8mb4 \ + -DDEFAULT_COLLATION=utf8mb4_general_ci \ + -DEXTRA_CHARSETS=all \ + -DCMAKE_EXE_LINKER_FLAGS='-ljemalloc' + make -j ${THREAD} + make install + popd + fi + + if [ -d "${mariadb_install_dir}/support-files" ]; then + sed -i "s+^dbrootpwd.*+dbrootpwd='${dbrootpwd}'+" ../config/options.conf + echo "${CSUCCESS}MariaDB installed successfully! ${CEND}" + if [ "${dbinstallmethod}" == "1" ]; then + rm -rf mariadb-${mariadb118_ver}-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == "2" ]; then + rm -rf mariadb-${mariadb118_ver} boost_${boostVersion2} + fi + else + rm -rf ${mariadb_install_dir} + echo "${CFAILURE}MariaDB install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + + /bin/cp ${mariadb_install_dir}/support-files/mysql.server /etc/init.d/mysqld + sed -i "s@^basedir=.*@basedir=${mariadb_install_dir}@" /etc/init.d/mysqld + sed -i "s@^datadir=.*@datadir=${mariadb_data_dir}@" /etc/init.d/mysqld + chmod +x /etc/init.d/mysqld + [ "${PM}" == 'yum' ] && { chkconfig --add mysqld; chkconfig mysqld on; } + [ "${PM}" == 'apt-get' ] && update-rc.d mysqld defaults + popd + + # my.cnf + cat > /etc/my.cnf << EOF +[client] +port = 3306 +socket = /tmp/mysql.sock +default-character-set = utf8mb4 + +[mysqld] +port = 3306 +socket = /tmp/mysql.sock + +basedir = ${mariadb_install_dir} +datadir = ${mariadb_data_dir} +pid-file = ${mariadb_data_dir}/mysql.pid +user = mysql +bind-address = 0.0.0.0 +server-id = 1 + +init-connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 + +skip-name-resolve +#skip-networking +back_log = 300 + +max_connections = 1000 +max_connect_errors = 6000 +open_files_limit = 65535 +table_open_cache = 128 +max_allowed_packet = 500M +binlog_cache_size = 1M +max_heap_table_size = 8M +tmp_table_size = 16M + +read_buffer_size = 2M +read_rnd_buffer_size = 8M +sort_buffer_size = 8M +join_buffer_size = 8M +key_buffer_size = 4M + +thread_cache_size = 8 + +query_cache_type = 1 +query_cache_size = 8M +query_cache_limit = 2M + +ft_min_word_len = 4 + +log_bin = mysql-bin +binlog_format = mixed +expire_logs_days = 7 + +log_error = ${mariadb_data_dir}/mysql-error.log +slow_query_log = 1 +long_query_time = 1 +slow_query_log_file = ${mariadb_data_dir}/mysql-slow.log + +performance_schema = 0 + +#lower_case_table_names = 1 + +skip-external-locking + +default_storage_engine = InnoDB +innodb_file_per_table = 1 +innodb_open_files = 500 +innodb_buffer_pool_size = 64M +innodb_write_io_threads = 4 +innodb_read_io_threads = 4 +innodb_purge_threads = 1 +innodb_flush_log_at_trx_commit = 2 +innodb_log_buffer_size = 2M +innodb_log_file_size = 32M +innodb_max_dirty_pages_pct = 90 +innodb_lock_wait_timeout = 120 + +bulk_insert_buffer_size = 8M +myisam_sort_buffer_size = 8M +myisam_max_sort_file_size = 10G + +interactive_timeout = 28800 +wait_timeout = 28800 + +[mysqldump] +quick +max_allowed_packet = 500M + +[myisamchk] +key_buffer_size = 8M +sort_buffer_size = 8M +read_buffer = 4M +write_buffer = 4M +EOF + + sed -i "s@max_connections.*@max_connections = $((${Mem}/3))@" /etc/my.cnf + if [ ${Mem} -gt 1500 -a ${Mem} -le 2500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 16M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 32M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf + elif [ ${Mem} -gt 2500 -a ${Mem} -le 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 32M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 512M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 64M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 512@' /etc/my.cnf + elif [ ${Mem} -gt 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 64@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 64M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf + fi + + ${mariadb_install_dir}/scripts/mysql_install_db --user=mysql --basedir=${mariadb_install_dir} --datadir=${mariadb_data_dir} + + [ "${Wsl}" == true ] && chmod 600 /etc/my.cnf + chown mysql.mysql -R ${mariadb_data_dir} + [ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} + service mysqld start + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mariadb_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mariadb_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mariadb_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'127.0.0.1' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'localhost' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.user where Password='' and User not like 'mariadb.%';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.db where User='';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.proxies_priv where Host!='localhost';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "drop database test;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" + rm -rf /etc/ld.so.conf.d/{mysql,mariadb,percona}*.conf + echo "${mariadb_install_dir}/lib" > /etc/ld.so.conf.d/z-mariadb.conf + ldconfig + service mysqld stop +} diff --git a/modules/db/mariadb-12.3.sh b/modules/db/mariadb-12.3.sh new file mode 100644 index 0000000..48b6e7d --- /dev/null +++ b/modules/db/mariadb-12.3.sh @@ -0,0 +1,215 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MariaDB123() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mysql >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin mysql + + [ ! -d "${mariadb_install_dir}" ] && mkdir -p ${mariadb_install_dir} + mkdir -p ${mariadb_data_dir};chown mysql.mysql -R ${mariadb_data_dir} + + if [ "${dbinstallmethod}" == "1" ]; then + tar zxf mariadb-${mariadb123_ver}-linux-systemd-x86_64.tar.gz + mv mariadb-${mariadb123_ver}-linux-systemd-x86_64/* ${mariadb_install_dir} + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mariadb_install_dir}/bin/mysqld_safe + sed -i "s@/usr/local/mysql@${mariadb_install_dir}@g" ${mariadb_install_dir}/bin/mysqld_safe + elif [ "${dbinstallmethod}" == "2" ]; then + boostVersion2=$(echo ${boost_oldver} | awk -F. '{print $1"_"$2"_"$3}') + tar xzf boost_${boostVersion2}.tar.gz + tar xzf mariadb-${mariadb123_ver}.tar.gz + pushd mariadb-${mariadb123_ver} + cmake . -DCMAKE_INSTALL_PREFIX=${mariadb_install_dir} \ + -DMYSQL_DATADIR=${mariadb_data_dir} \ + -DDOWNLOAD_BOOST=1 \ + -DWITH_BOOST=../boost_${boostVersion2} \ + -DSYSCONFDIR=/etc \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 \ + -DWITH_PARTITION_STORAGE_ENGINE=1 \ + -DWITH_FEDERATED_STORAGE_ENGINE=1 \ + -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ + -DWITH_MYISAM_STORAGE_ENGINE=1 \ + -DWITH_EMBEDDED_SERVER=1 \ + -DENABLE_DTRACE=0 \ + -DENABLED_LOCAL_INFILE=1 \ + -DDEFAULT_CHARSET=utf8mb4 \ + -DDEFAULT_COLLATION=utf8mb4_general_ci \ + -DEXTRA_CHARSETS=all \ + -DCMAKE_EXE_LINKER_FLAGS='-ljemalloc' + make -j ${THREAD} + make install + popd + fi + + if [ -d "${mariadb_install_dir}/support-files" ]; then + sed -i "s+^dbrootpwd.*+dbrootpwd='${dbrootpwd}'+" ../config/options.conf + echo "${CSUCCESS}MariaDB installed successfully! ${CEND}" + if [ "${dbinstallmethod}" == "1" ]; then + rm -rf mariadb-${mariadb123_ver}-linux-systemd-x86_64 + elif [ "${dbinstallmethod}" == "2" ]; then + rm -rf mariadb-${mariadb123_ver} boost_${boostVersion2} + fi + else + rm -rf ${mariadb_install_dir} + echo "${CFAILURE}MariaDB install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + + /bin/cp ${mariadb_install_dir}/support-files/mysql.server /etc/init.d/mysqld + sed -i "s@^basedir=.*@basedir=${mariadb_install_dir}@" /etc/init.d/mysqld + sed -i "s@^datadir=.*@datadir=${mariadb_data_dir}@" /etc/init.d/mysqld + chmod +x /etc/init.d/mysqld + [ "${PM}" == 'yum' ] && { chkconfig --add mysqld; chkconfig mysqld on; } + [ "${PM}" == 'apt-get' ] && update-rc.d mysqld defaults + popd + + # my.cnf + cat > /etc/my.cnf << EOF +[client] +port = 3306 +socket = /tmp/mysql.sock +default-character-set = utf8mb4 + +[mysqld] +port = 3306 +socket = /tmp/mysql.sock + +basedir = ${mariadb_install_dir} +datadir = ${mariadb_data_dir} +pid-file = ${mariadb_data_dir}/mysql.pid +user = mysql +bind-address = 0.0.0.0 +server-id = 1 + +init-connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 + +skip-name-resolve +#skip-networking +back_log = 300 + +max_connections = 1000 +max_connect_errors = 6000 +open_files_limit = 65535 +table_open_cache = 128 +max_allowed_packet = 500M +binlog_cache_size = 1M +max_heap_table_size = 8M +tmp_table_size = 16M + +read_buffer_size = 2M +read_rnd_buffer_size = 8M +sort_buffer_size = 8M +join_buffer_size = 8M +key_buffer_size = 4M + +thread_cache_size = 8 + +query_cache_type = 1 +query_cache_size = 8M +query_cache_limit = 2M + +ft_min_word_len = 4 + +log_bin = mysql-bin +binlog_format = mixed +expire_logs_days = 7 + +log_error = ${mariadb_data_dir}/mysql-error.log +slow_query_log = 1 +long_query_time = 1 +slow_query_log_file = ${mariadb_data_dir}/mysql-slow.log + +performance_schema = 0 + +#lower_case_table_names = 1 + +skip-external-locking + +default_storage_engine = InnoDB +innodb_file_per_table = 1 +innodb_open_files = 500 +innodb_buffer_pool_size = 64M +innodb_write_io_threads = 4 +innodb_read_io_threads = 4 +innodb_purge_threads = 1 +innodb_flush_log_at_trx_commit = 2 +innodb_log_buffer_size = 2M +innodb_log_file_size = 32M +innodb_max_dirty_pages_pct = 90 +innodb_lock_wait_timeout = 120 + +bulk_insert_buffer_size = 8M +myisam_sort_buffer_size = 8M +myisam_max_sort_file_size = 10G + +interactive_timeout = 28800 +wait_timeout = 28800 + +[mysqldump] +quick +max_allowed_packet = 500M + +[myisamchk] +key_buffer_size = 8M +sort_buffer_size = 8M +read_buffer = 4M +write_buffer = 4M +EOF + + sed -i "s@max_connections.*@max_connections = $((${Mem}/3))@" /etc/my.cnf + if [ ${Mem} -gt 1500 -a ${Mem} -le 2500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 16M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 32M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf + elif [ ${Mem} -gt 2500 -a ${Mem} -le 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 32M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 512M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 64M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 512@' /etc/my.cnf + elif [ ${Mem} -gt 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 64@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 64M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf + fi + + ${mariadb_install_dir}/scripts/mysql_install_db --user=mysql --basedir=${mariadb_install_dir} --datadir=${mariadb_data_dir} + + [ "${Wsl}" == true ] && chmod 600 /etc/my.cnf + chown mysql.mysql -R ${mariadb_data_dir} + [ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} + service mysqld start + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mariadb_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mariadb_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mariadb_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'127.0.0.1' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'localhost' identified by \"${dbrootpwd}\" with grant option;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.user where Password='' and User not like 'mariadb.%';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.db where User='';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "delete from mysql.proxies_priv where Host!='localhost';" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "drop database test;" + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" + rm -rf /etc/ld.so.conf.d/{mysql,mariadb,percona}*.conf + echo "${mariadb_install_dir}/lib" > /etc/ld.so.conf.d/z-mariadb.conf + ldconfig + service mysqld stop +} diff --git a/modules/db/mongodb.sh b/modules/db/mongodb.sh new file mode 100644 index 0000000..5336926 --- /dev/null +++ b/modules/db/mongodb.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MongoDB() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mongod >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -s /sbin/nologin mongod + mkdir -p ${mongo_data_dir};chown mongod.mongod -R ${mongo_data_dir} + tar xzf mongodb-linux-x86_64-${mongodb_ver}.tgz + /bin/mv mongodb-linux-x86_64-${mongodb_ver} ${mongo_install_dir} + /bin/cp ${oneinstack_dir}/services/mongod.service /lib/systemd/system/ + sed -i "s@=/usr/local/mongodb@=${mongo_install_dir}@g" /lib/systemd/system/mongod.service + systemctl enable mongod + + cat > /etc/mongod.conf << EOF +# mongod.conf + +# for documentation of all options, see: +# http://docs.mongodb.org/manual/reference/configuration-options/ + +# where to write logging data. +systemLog: + destination: file + logAppend: true + path: ${mongo_data_dir}/mongod.log + +# Where and how to store data. +storage: + dbPath: ${mongo_data_dir} + journal: + enabled: true +# engine: +# mmapv1: +# wiredTiger: + +# how the process runs +processManagement: + fork: true # fork and run in background + pidFilePath: /var/run/mongodb/mongod.pid + +# network interfaces +net: + port: 27017 + bindIp: 0.0.0.0 + unixDomainSocket: + enabled: false + +#security: +# authorization: enabled + +#operationProfiling: +#replication: +#sharding: +EOF + systemctl start mongod + echo ${mongo_install_dir}/bin/mongo 127.0.0.1/admin --eval \"db.createUser\(\{user:\'root\',pwd:\'$dbmongopwd\',roles:[\'userAdminAnyDatabase\']\}\)\" | bash + sed -i 's@^#security:@security:@' /etc/mongod.conf + sed -i 's@^# authorization:@ authorization:@' /etc/mongod.conf + if [ -e "${mongo_install_dir}/bin/mongo" ]; then + sed -i "s+^dbmongopwd.*+dbmongopwd='$dbmongopwd'+" ../config/options.conf + echo "${CSUCCESS}MongoDB installed successfully! ${CEND}" + rm -rf mongodb-linux-x86_64-${mongodb_ver} + else + rm -rf ${mongo_install_dir} ${mongo_data_dir} + echo "${CFAILURE}MongoDB install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mongo_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mongo_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mongo_install_dir}/bin:\1@" /etc/profile + . /etc/profile +} diff --git a/modules/db/mysql-5.7.sh b/modules/db/mysql-5.7.sh new file mode 100644 index 0000000..eca00fc --- /dev/null +++ b/modules/db/mysql-5.7.sh @@ -0,0 +1,219 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MySQL57() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mysql >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin mysql + + [ ! -d "${mysql_install_dir}" ] && mkdir -p ${mysql_install_dir} + mkdir -p ${mysql_data_dir};chown mysql.mysql -R ${mysql_data_dir} + + if [ "${dbinstallmethod}" == "1" ]; then + tar xzf mysql-${mysql57_ver}-linux-glibc2.12-x86_64.tar.gz + mv mysql-${mysql57_ver}-linux-glibc2.12-x86_64/* ${mysql_install_dir} + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mysql_install_dir}/bin/mysqld_safe + sed -i "s@/usr/local/mysql@${mysql_install_dir}@g" ${mysql_install_dir}/bin/mysqld_safe + elif [ "${dbinstallmethod}" == "2" ]; then + boostVersion2=$(echo ${boost_oldver} | awk -F. '{print $1"_"$2"_"$3}') + tar xzf boost_${boostVersion2}.tar.gz + tar xzf mysql-${mysql57_ver}.tar.gz + pushd mysql-${mysql57_ver} + cmake . -DCMAKE_INSTALL_PREFIX=${mysql_install_dir} \ + -DMYSQL_DATADIR=${mysql_data_dir} \ + -DDOWNLOAD_BOOST=1 \ + -DWITH_BOOST=../boost_${boostVersion2} \ + -DSYSCONFDIR=/etc \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 \ + -DWITH_PARTITION_STORAGE_ENGINE=1 \ + -DWITH_FEDERATED_STORAGE_ENGINE=1 \ + -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ + -DWITH_MYISAM_STORAGE_ENGINE=1 \ + -DWITH_EMBEDDED_SERVER=1 \ + -DENABLE_DTRACE=0 \ + -DENABLED_LOCAL_INFILE=1 \ + -DDEFAULT_CHARSET=utf8mb4 \ + -DDEFAULT_COLLATION=utf8mb4_general_ci \ + -DEXTRA_CHARSETS=all \ + -DCMAKE_EXE_LINKER_FLAGS='-ljemalloc' + make -j ${THREAD} + make install + popd + fi + + if [ -d "${mysql_install_dir}/support-files" ]; then + sed -i "s+^dbrootpwd.*+dbrootpwd='${dbrootpwd}'+" ../config/options.conf + echo "${CSUCCESS}MySQL installed successfully! ${CEND}" + if [ "${dbinstallmethod}" == "1" ]; then + rm -rf mysql-${mysql57_ver}-*-x86_64 + elif [ "${dbinstallmethod}" == "2" ]; then + rm -rf mysql-${mysql57_ver} boost_${boostVersion2} + fi + else + rm -rf ${mysql_install_dir} + echo "${CFAILURE}MySQL install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + + /bin/cp ${mysql_install_dir}/support-files/mysql.server /etc/init.d/mysqld + sed -i "s@^basedir=.*@basedir=${mysql_install_dir}@" /etc/init.d/mysqld + sed -i "s@^datadir=.*@datadir=${mysql_data_dir}@" /etc/init.d/mysqld + chmod +x /etc/init.d/mysqld + [ "${PM}" == 'yum' ] && { chkconfig --add mysqld; chkconfig mysqld on; } + [ "${PM}" == 'apt-get' ] && update-rc.d mysqld defaults + popd + + # my.cnf + cat > /etc/my.cnf << EOF +[client] +port = 3306 +socket = /tmp/mysql.sock + +[mysql] +prompt="MySQL [\\d]> " +no-auto-rehash + +[mysqld] +port = 3306 +socket = /tmp/mysql.sock + +basedir = ${mysql_install_dir} +datadir = ${mysql_data_dir} +pid-file = ${mysql_data_dir}/mysql.pid +user = mysql +bind-address = 0.0.0.0 +server-id = 1 + +init-connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 + +skip-name-resolve +#skip-networking +back_log = 300 + +max_connections = 1000 +max_connect_errors = 6000 +open_files_limit = 65535 +table_open_cache = 128 +max_allowed_packet = 500M +binlog_cache_size = 1M +max_heap_table_size = 8M +tmp_table_size = 16M + +read_buffer_size = 2M +read_rnd_buffer_size = 8M +sort_buffer_size = 8M +join_buffer_size = 8M +key_buffer_size = 4M + +thread_cache_size = 8 + +query_cache_type = 1 +query_cache_size = 8M +query_cache_limit = 2M + +ft_min_word_len = 4 + +log_bin = mysql-bin +binlog_format = mixed +expire_logs_days = 7 + +log_error = ${mysql_data_dir}/mysql-error.log +slow_query_log = 1 +long_query_time = 1 +slow_query_log_file = ${mysql_data_dir}/mysql-slow.log + +performance_schema = 0 +explicit_defaults_for_timestamp + +#lower_case_table_names = 1 + +skip-external-locking + +default_storage_engine = InnoDB +#default-storage-engine = MyISAM +innodb_file_per_table = 1 +innodb_open_files = 500 +innodb_buffer_pool_size = 64M +innodb_write_io_threads = 4 +innodb_read_io_threads = 4 +innodb_thread_concurrency = 0 +innodb_purge_threads = 1 +innodb_flush_log_at_trx_commit = 2 +innodb_log_buffer_size = 2M +innodb_log_file_size = 32M +innodb_log_files_in_group = 3 +innodb_max_dirty_pages_pct = 90 +innodb_lock_wait_timeout = 120 + +bulk_insert_buffer_size = 8M +myisam_sort_buffer_size = 8M +myisam_max_sort_file_size = 10G + +interactive_timeout = 28800 +wait_timeout = 28800 + +[mysqldump] +quick +max_allowed_packet = 500M + +[myisamchk] +key_buffer_size = 8M +sort_buffer_size = 8M +read_buffer = 4M +write_buffer = 4M +EOF + + sed -i "s@max_connections.*@max_connections = $((${Mem}/3))@" /etc/my.cnf + if [ ${Mem} -gt 1500 -a ${Mem} -le 2500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 16M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 32M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf + elif [ ${Mem} -gt 2500 -a ${Mem} -le 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 32M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 512M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 64M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 512@' /etc/my.cnf + elif [ ${Mem} -gt 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 64@' /etc/my.cnf + sed -i 's@^query_cache_size.*@query_cache_size = 64M@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf + fi + + ${mysql_install_dir}/bin/mysqld --initialize-insecure --user=mysql --basedir=${mysql_install_dir} --datadir=${mysql_data_dir} + + [ "${Wsl}" == true ] && chmod 600 /etc/my.cnf + chown mysql.mysql -R ${mysql_data_dir} + [ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} + service mysqld start + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mysql_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mysql_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mysql_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + ${mysql_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'127.0.0.1' identified by \"${dbrootpwd}\" with grant option;" + ${mysql_install_dir}/bin/mysql -e "grant all privileges on *.* to root@'localhost' identified by \"${dbrootpwd}\" with grant option;" + ${mysql_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" + rm -rf /etc/ld.so.conf.d/{mysql,mariadb,percona}*.conf + [ -e "${mysql_install_dir}/my.cnf" ] && rm -f ${mysql_install_dir}/my.cnf + echo "${mysql_install_dir}/lib" > /etc/ld.so.conf.d/z-mysql.conf + ldconfig + service mysqld stop +} diff --git a/modules/db/mysql-8.0.sh b/modules/db/mysql-8.0.sh new file mode 100644 index 0000000..1a821b0 --- /dev/null +++ b/modules/db/mysql-8.0.sh @@ -0,0 +1,220 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MySQL80() { + pushd ${oneinstack_dir}/src > /dev/null + id -u mysql >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -M -s /sbin/nologin mysql + + [ ! -d "${mysql_install_dir}" ] && mkdir -p ${mysql_install_dir} + mkdir -p ${mysql_data_dir};chown mysql.mysql -R ${mysql_data_dir} + + if [ "${dbinstallmethod}" == "1" ]; then + tar xJf mysql-${mysql80_ver}-linux-glibc2.12-x86_64.tar.xz + mv mysql-${mysql80_ver}-linux-glibc2.12-x86_64/* ${mysql_install_dir} + sed -i "s@/usr/local/mysql@${mysql_install_dir}@g" ${mysql_install_dir}/bin/mysqld_safe + elif [ "${dbinstallmethod}" == "2" ]; then + boostVersion2=$(echo ${boost_ver} | awk -F. '{print $1"_"$2"_"$3}') + tar xzf boost_${boostVersion2}.tar.gz + tar xzf mysql-${mysql80_ver}.tar.gz + pushd mysql-${mysql80_ver} + [ -e "/usr/bin/cmake3" ] && CMAKE=cmake3 || CMAKE=cmake + $CMAKE . -DCMAKE_INSTALL_PREFIX=${mysql_install_dir} \ + -DMYSQL_DATADIR=${mysql_data_dir} \ + -DDOWNLOAD_BOOST=1 \ + -DWITH_BOOST=../boost_${boostVersion2} \ + -DFORCE_INSOURCE_BUILD=1 \ + -DSYSCONFDIR=/etc \ + -DWITH_INNOBASE_STORAGE_ENGINE=1 \ + -DWITH_FEDERATED_STORAGE_ENGINE=1 \ + -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ + -DWITH_MYISAM_STORAGE_ENGINE=1 \ + -DENABLED_LOCAL_INFILE=1 \ + -DFORCE_INSOURCE_BUILD=1 \ + -DCMAKE_C_COMPILER=/usr/bin/gcc \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++ \ + -DDEFAULT_CHARSET=utf8mb4 + make -j ${THREAD} + make install + popd + fi + + # backup openssl so + #[ ! -e "${mysql_install_dir}/lib/lib_bk" ] && mkdir ${mysql_install_dir}/lib/lib_bk + #/bin/mv ${mysql_install_dir}/lib/{libssl,libcrypto}.so* ${mysql_install_dir}/lib/lib_bk/ + + if [ -d "${mysql_install_dir}/support-files" ]; then + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mysql_install_dir}/bin/mysqld_safe + sed -i "s+^dbrootpwd.*+dbrootpwd='${dbrootpwd}'+" ../config/options.conf + echo "${CSUCCESS}MySQL installed successfully! ${CEND}" + if [ "${dbinstallmethod}" == "1" ]; then + rm -rf mysql-${mysql80_ver}-*-x86_64 + elif [ "${dbinstallmethod}" == "2" ]; then + rm -rf mysql-${mysql80_ver} boost_${boostVersion2} + fi + else + rm -rf ${mysql_install_dir} + echo "${CFAILURE}MySQL install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + + /bin/cp ${mysql_install_dir}/support-files/mysql.server /etc/init.d/mysqld + sed -i "s@^basedir=.*@basedir=${mysql_install_dir}@" /etc/init.d/mysqld + sed -i "s@^datadir=.*@datadir=${mysql_data_dir}@" /etc/init.d/mysqld + chmod +x /etc/init.d/mysqld + [ "${PM}" == 'yum' ] && { chkconfig --add mysqld; chkconfig mysqld on; } + [ "${PM}" == 'apt-get' ] && update-rc.d mysqld defaults + popd + + # my.cnf + cat > /etc/my.cnf << EOF +[client] +port = 3306 +socket = /tmp/mysql.sock +default-character-set = utf8mb4 + +[mysql] +prompt="MySQL [\\d]> " +no-auto-rehash + +[mysqld] +port = 3306 +socket = /tmp/mysql.sock +default_authentication_plugin = mysql_native_password + +basedir = ${mysql_install_dir} +datadir = ${mysql_data_dir} +pid-file = ${mysql_data_dir}/mysql.pid +user = mysql +bind-address = 0.0.0.0 +server-id = 1 + +init-connect = 'SET NAMES utf8mb4' +character-set-server = utf8mb4 +collation-server = utf8mb4_0900_ai_ci + +skip-name-resolve +#skip-networking +back_log = 300 + +max_connections = 1000 +max_connect_errors = 6000 +open_files_limit = 65535 +table_open_cache = 128 +max_allowed_packet = 500M +binlog_cache_size = 1M +max_heap_table_size = 8M +tmp_table_size = 16M + +read_buffer_size = 2M +read_rnd_buffer_size = 8M +sort_buffer_size = 8M +join_buffer_size = 8M +key_buffer_size = 4M + +thread_cache_size = 8 + +ft_min_word_len = 4 + +log_bin = mysql-bin +binlog_format = mixed +binlog_expire_logs_seconds = 604800 + +log_error = ${mysql_data_dir}/mysql-error.log +slow_query_log = 1 +long_query_time = 1 +slow_query_log_file = ${mysql_data_dir}/mysql-slow.log + +performance_schema = 0 +explicit_defaults_for_timestamp + +#lower_case_table_names = 1 + +skip-external-locking + +default_storage_engine = InnoDB +#default-storage-engine = MyISAM +innodb_file_per_table = 1 +innodb_open_files = 500 +innodb_buffer_pool_size = 64M +innodb_write_io_threads = 4 +innodb_read_io_threads = 4 +innodb_thread_concurrency = 0 +innodb_purge_threads = 1 +innodb_flush_log_at_trx_commit = 2 +innodb_log_buffer_size = 2M +innodb_log_file_size = 32M +innodb_log_files_in_group = 3 +innodb_max_dirty_pages_pct = 90 +innodb_lock_wait_timeout = 120 + +bulk_insert_buffer_size = 8M +myisam_sort_buffer_size = 8M +myisam_max_sort_file_size = 10G + +interactive_timeout = 28800 +wait_timeout = 28800 + +[mysqldump] +quick +max_allowed_packet = 500M + +[myisamchk] +key_buffer_size = 8M +sort_buffer_size = 8M +read_buffer = 4M +write_buffer = 4M +EOF + + sed -i "s@max_connections.*@max_connections = $((${Mem}/3))@" /etc/my.cnf + if [ ${Mem} -gt 1500 -a ${Mem} -le 2500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 16@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 16M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 128M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 32M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 256@' /etc/my.cnf + elif [ ${Mem} -gt 2500 -a ${Mem} -le 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 32@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 32M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 512M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 64M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 512@' /etc/my.cnf + elif [ ${Mem} -gt 3500 ]; then + sed -i 's@^thread_cache_size.*@thread_cache_size = 64@' /etc/my.cnf + sed -i 's@^myisam_sort_buffer_size.*@myisam_sort_buffer_size = 64M@' /etc/my.cnf + sed -i 's@^key_buffer_size.*@key_buffer_size = 256M@' /etc/my.cnf + sed -i 's@^innodb_buffer_pool_size.*@innodb_buffer_pool_size = 1024M@' /etc/my.cnf + sed -i 's@^tmp_table_size.*@tmp_table_size = 128M@' /etc/my.cnf + sed -i 's@^table_open_cache.*@table_open_cache = 1024@' /etc/my.cnf + fi + + ${mysql_install_dir}/bin/mysqld --initialize-insecure --user=mysql --basedir=${mysql_install_dir} --datadir=${mysql_data_dir} + + [ "${Wsl}" == true ] && chmod 600 /etc/my.cnf + chown mysql.mysql -R ${mysql_data_dir} + [ -d "/etc/mysql" ] && /bin/mv /etc/mysql{,_bk} + service mysqld start + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${mysql_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${mysql_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${mysql_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + ${mysql_install_dir}/bin/mysql -uroot -hlocalhost -e "create user root@'127.0.0.1' identified by \"${dbrootpwd}\";" + ${mysql_install_dir}/bin/mysql -uroot -hlocalhost -e "grant all privileges on *.* to root@'127.0.0.1' with grant option;" + ${mysql_install_dir}/bin/mysql -uroot -hlocalhost -e "grant all privileges on *.* to root@'localhost' with grant option;" + ${mysql_install_dir}/bin/mysql -uroot -hlocalhost -e "alter user root@'localhost' identified by \"${dbrootpwd}\";" + ${mysql_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" + rm -rf /etc/ld.so.conf.d/{mysql,mariadb,percona}*.conf + [ -e "${mysql_install_dir}/my.cnf" ] && rm -f ${mysql_install_dir}/my.cnf + echo "${mysql_install_dir}/lib" > /etc/ld.so.conf.d/z-mysql.conf + ldconfig + service mysqld stop +} diff --git a/modules/db/postgresql.sh b/modules/db/postgresql.sh new file mode 100644 index 0000000..eda5535 --- /dev/null +++ b/modules/db/postgresql.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_PostgreSQL() { + pushd ${oneinstack_dir}/src > /dev/null + id -u postgres >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -d ${pgsql_install_dir} -s /bin/bash postgres + mkdir -p ${pgsql_data_dir};chown postgres.postgres -R ${pgsql_data_dir} + tar xzf postgresql-${pgsql_ver}.tar.gz + pushd postgresql-${pgsql_ver} + ./configure --prefix=$pgsql_install_dir + make -j ${THREAD} + make install + chmod 755 ${pgsql_install_dir} + chown -R postgres.postgres ${pgsql_install_dir} + /bin/cp ${oneinstack_dir}/services/postgresql.service /lib/systemd/system/ + sed -i "s@=/usr/local/pgsql@=${pgsql_install_dir}@g" /lib/systemd/system/postgresql.service + sed -i "s@PGDATA=.*@PGDATA=${pgsql_data_dir}@" /lib/systemd/system/postgresql.service + systemctl enable postgresql + popd + su - postgres -c "${pgsql_install_dir}/bin/initdb -D ${pgsql_data_dir}" + systemctl start postgresql + sleep 5 + su - postgres -c "${pgsql_install_dir}/bin/psql -c \"alter user postgres with password '$dbpostgrespwd';\"" + sed -i 's@^host.*@#&@g' ${pgsql_data_dir}/pg_hba.conf + sed -i 's@^local.*@#&@g' ${pgsql_data_dir}/pg_hba.conf + echo 'local all all md5' >> ${pgsql_data_dir}/pg_hba.conf + echo 'host all all 0.0.0.0/0 md5' >> ${pgsql_data_dir}/pg_hba.conf + sed -i "s@^#listen_addresses.*@listen_addresses = '*'@" ${pgsql_data_dir}/postgresql.conf + systemctl reload postgresql + + if [ -e "${pgsql_install_dir}/bin/psql" ]; then + sed -i "s+^dbpostgrespwd.*+dbpostgrespwd='$dbpostgrespwd'+" ../config/options.conf + echo "${CSUCCESS}PostgreSQL installed successfully! ${CEND}" + else + rm -rf ${pgsql_install_dir} ${pgsql_data_dir} + echo "${CFAILURE}PostgreSQL install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd + [ -z "$(grep ^'export PATH=' /etc/profile)" ] && echo "export PATH=${pgsql_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "$(grep ^'export PATH=' /etc/profile)" -a -z "$(grep ${pgsql_install_dir} /etc/profile)" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${pgsql_install_dir}/bin:\1@" /etc/profile + . /etc/profile +} diff --git a/modules/ftp/pureftpd.sh b/modules/ftp/pureftpd.sh new file mode 100644 index 0000000..610009c --- /dev/null +++ b/modules/ftp/pureftpd.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_PureFTPd() { + pushd ${oneinstack_dir}/src > /dev/null + id -g ${run_group} >/dev/null 2>&1 + [ $? -ne 0 ] && groupadd ${run_group} + id -u ${run_user} >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -g ${run_group} -M -s /sbin/nologin ${run_user} + + tar xzf pure-ftpd-${pureftpd_ver}.tar.gz + pushd pure-ftpd-${pureftpd_ver} > /dev/null + [ ! -d "${pureftpd_install_dir}" ] && mkdir -p ${pureftpd_install_dir} + ./configure --prefix=${pureftpd_install_dir} CFLAGS=-O2 --with-puredb --with-quotas --with-cookie --with-virtualhosts --with-virtualchroot --with-diraliases --with-sysquotas --with-ratios --with-altlog --with-paranoidmsg --with-shadow --with-welcomemsg --with-throttling --with-uploadscript --with-language=english --with-tls + make -j ${THREAD} && make install + popd > /dev/null + if [ -e "${pureftpd_install_dir}/sbin/pure-ftpwho" ]; then + /bin/cp ../services/pureftpd.service /lib/systemd/system/ + sed -i "s@/usr/local/pureftpd@${pureftpd_install_dir}@g" /lib/systemd/system/pureftpd.service + systemctl enable pureftpd + + [ ! -e "${pureftpd_install_dir}/etc" ] && mkdir ${pureftpd_install_dir}/etc + /bin/cp ../config/pure-ftpd.conf ${pureftpd_install_dir}/etc + sed -i "s@^PureDB.*@PureDB ${pureftpd_install_dir}/etc/pureftpd.pdb@" ${pureftpd_install_dir}/etc/pure-ftpd.conf + sed -i "s@^LimitRecursion.*@LimitRecursion 65535 8@" ${pureftpd_install_dir}/etc/pure-ftpd.conf + IPADDR=${IPADDR:-127.0.0.1} + [ ! -d /etc/ssl/private ] && mkdir -p /etc/ssl/private + openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 2048 + openssl req -x509 -days 7300 -sha256 -nodes -subj "/C=CN/ST=Shanghai/L=Shanghai/O=OneinStack/CN=${IPADDR}" -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem + chmod 600 /etc/ssl/private/pure-ftpd*.pem + sed -i "s@^# TLS.*@&\nCertFile /etc/ssl/private/pure-ftpd.pem@" ${pureftpd_install_dir}/etc/pure-ftpd.conf + sed -i "s@^# TLS.*@&\nTLSCipherSuite HIGH:MEDIUM:+TLSv1:\!SSLv2:\!SSLv3@" ${pureftpd_install_dir}/etc/pure-ftpd.conf + sed -i "s@^# TLS.*@TLS 1@" ${pureftpd_install_dir}/etc/pure-ftpd.conf + ulimit -s unlimited + systemctl start pureftpd + + # iptables Ftp + if [ "${PM}" == 'yum' ]; then + if [ -n "`grep 'dport 80 ' /etc/sysconfig/iptables`" ] && [ -z "$(grep '20000:30000' /etc/sysconfig/iptables)" ]; then + iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT + iptables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 20000:30000 -j ACCEPT + service iptables save + ip6tables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT + ip6tables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 20000:30000 -j ACCEPT + service ip6tables save + fi + elif [ "${PM}" == 'apt-get' ]; then + if [ -e '/etc/iptables/rules.v4' ]; then + if [ -n "`grep 'dport 80 ' /etc/iptables/rules.v4`" ] && [ -z "$(grep '20000:30000' /etc/iptables/rules.v4)" ]; then + iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT + iptables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 20000:30000 -j ACCEPT + iptables-save > /etc/iptables/rules.v4 + ip6tables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT + ip6tables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 20000:30000 -j ACCEPT + ip6tables-save > /etc/iptables/rules.v6 + fi + elif [ -e '/etc/iptables.up.rules' ]; then + if [ -n "`grep 'dport 80 ' /etc/iptables.up.rules`" ] && [ -z "$(grep '20000:30000' /etc/iptables.up.rules)" ]; then + iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT + iptables -I INPUT 6 -p tcp -m state --state NEW -m tcp --dport 20000:30000 -j ACCEPT + iptables-save > /etc/iptables.up.rules + fi + fi + fi + + echo "${CSUCCESS}Pure-Ftp installed successfully! ${CEND}" + rm -rf pure-ftpd-${pureftpd_ver} + else + rm -rf ${pureftpd_install_dir} + echo "${CFAILURE}Pure-Ftpd install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd > /dev/null +} diff --git a/modules/image/GraphicsMagick.sh b/modules/image/GraphicsMagick.sh new file mode 100644 index 0000000..2f9025e --- /dev/null +++ b/modules/image/GraphicsMagick.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_GraphicsMagick() { + if [ -d "${gmagick_install_dir}" ]; then + echo "${CWARNING}GraphicsMagick already installed! ${CEND}" + else + pushd ${oneinstack_dir}/src > /dev/null + tar xzf GraphicsMagick-${graphicsmagick_ver}.tar.gz + pushd GraphicsMagick-${graphicsmagick_ver} > /dev/null + ./configure --prefix=${gmagick_install_dir} --enable-shared --enable-static --enable-symbol-prefix + make -j ${THREAD} && make install + popd > /dev/null + rm -rf GraphicsMagick-${graphicsmagick_ver} + popd > /dev/null + fi +} + +Uninstall_GraphicsMagick() { + if [ -d "${gmagick_install_dir}" ]; then + rm -rf ${gmagick_install_dir} + echo; echo "${CMSG}GraphicsMagick uninstall completed${CEND}" + fi +} + +Install_pecl_gmagick() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + if [ "`${php_install_dir}/bin/php-config --version | awk -F. '{print $1}'`" == '5' ]; then + tar xzf gmagick-${gmagick_oldver}.tgz + pushd gmagick-${gmagick_oldver} > /dev/null + else + tar xzf gmagick-${gmagick_ver}.tgz + pushd gmagick-${gmagick_ver} > /dev/null + fi + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --with-gmagick=${gmagick_install_dir} + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/gmagick.so" ]; then + echo 'extension=gmagick.so' > ${php_install_dir}/etc/php.d/03-gmagick.ini + echo "${CSUCCESS}PHP gmagick module installed successfully! ${CEND}" + rm -rf gmagick-${gmagick_ver} gmagick-${gmagick_oldver} + else + echo "${CFAILURE}PHP gmagick module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_gmagick() { + if [ -e "${php_install_dir}/etc/php.d/03-gmagick.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/03-gmagick.ini + echo; echo "${CMSG}PHP gmagick module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP gmagick module does not exist! ${CEND}" + fi +} diff --git a/modules/image/ImageMagick.sh b/modules/image/ImageMagick.sh new file mode 100644 index 0000000..c8a842c --- /dev/null +++ b/modules/image/ImageMagick.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_ImageMagick() { + if [ -d "${imagick_install_dir}" ]; then + echo "${CWARNING}ImageMagick already installed! ${CEND}" + else + pushd ${oneinstack_dir}/src > /dev/null + tar xzf ImageMagick-${imagemagick_ver}.tar.gz + #if [ "${PM}" == 'yum' ]; then + # yum -y install libwebp-devel + #elif [ "${PM}" == 'apt-get' ]; then + # yum -y install libwebp-dev + #fi + pushd ImageMagick-${imagemagick_ver} > /dev/null + ./configure --prefix=${imagick_install_dir} --enable-shared --enable-static + make -j ${THREAD} && make install + popd > /dev/null + rm -rf ImageMagick-${imagemagick_ver} + popd > /dev/null + fi +} + +Uninstall_ImageMagick() { + if [ -d "${imagick_install_dir}" ]; then + rm -rf ${imagick_install_dir} + echo; echo "${CMSG}ImageMagick uninstall completed${CEND}" + fi +} + +Install_pecl_imagick() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + if [[ "${PHP_main_ver}" =~ ^5.3$ ]]; then + tar xzf imagick-${imagick_oldver}.tgz + pushd imagick-${imagick_oldver} > /dev/null + else + tar xzf imagick-${imagick_ver}.tgz + pushd imagick-${imagick_ver} > /dev/null + fi + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --with-imagick=${imagick_install_dir} + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/imagick.so" ]; then + echo 'extension=imagick.so' > ${php_install_dir}/etc/php.d/03-imagick.ini + echo "${CSUCCESS}PHP imagick module installed successfully! ${CEND}" + rm -rf imagick-${imagick_ver} imagick-${imagick_oldver} + else + echo "${CFAILURE}PHP imagick module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_imagick() { + if [ -e "${php_install_dir}/etc/php.d/03-imagick.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/03-imagick.ini + echo; echo "${CMSG}PHP imagick module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP imagick module does not exist! ${CEND}" + fi +} diff --git a/modules/lang/nodejs.sh b/modules/lang/nodejs.sh new file mode 100644 index 0000000..c8d7778 --- /dev/null +++ b/modules/lang/nodejs.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_Nodejs() { + pushd ${oneinstack_dir}/src > /dev/null + tar xzf node-v${nodejs_ver}-linux-${SYS_ARCH_n}.tar.gz + /bin/mv node-v${nodejs_ver}-linux-${SYS_ARCH_n} ${nodejs_install_dir} + if [ -e "${nodejs_install_dir}/bin/node" ]; then + cat > /etc/profile.d/nodejs.sh << EOF +export NODE_HOME=${nodejs_install_dir} +export PATH=\$NODE_HOME/bin:\$PATH +EOF + . /etc/profile + echo "${CSUCCESS}Nodejs installed successfully! ${CEND}" + else + echo "${CFAILURE}Nodejs install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd > /dev/null +} + +Uninstall_Nodejs() { + if [ -e "${nodejs_install_dir}" ]; then + rm -rf ${nodejs_install_dir} /etc/profile.d/nodejs.sh + echo "${CMSG}Nodejs uninstall completed! ${CEND}" + fi +} + diff --git a/modules/lang/python.sh b/modules/lang/python.sh new file mode 100644 index 0000000..59cdbd2 --- /dev/null +++ b/modules/lang/python.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_Python() { + if [ -e "${python_install_dir}/bin/python" ]; then + echo "${CWARNING}Python already installed! ${CEND}" + else + pushd ${oneinstack_dir}/src > /dev/null + + if [ "${PM}" == 'yum' ]; then + [ -z "`grep -w epel /etc/yum.repos.d/*.repo`" ] && yum -y install epel-release + pkgList="gcc dialog augeas-libs openssl openssl-devel libffi-devel redhat-rpm-config ca-certificates" + for Package in ${pkgList}; do + yum -y install ${Package} + done + elif [ "${PM}" == 'apt-get' ]; then + pkgList="gcc dialog libaugeas0 augeas-lenses libssl-dev libffi-dev ca-certificates" + for Package in ${pkgList}; do + apt-get -y install $Package + done + fi + + # Install Python3 + if [ ! -e "${python_install_dir}/bin/python" -a ! -e "${python_install_dir}/bin/python3" ] ;then + src_url=http://mirrors.linuxeye.com/oneinstack/src/Python-${python_ver}.tgz && Download_src + tar xzf Python-${python_ver}.tgz + pushd Python-${python_ver} > /dev/null + ./configure --prefix=${python_install_dir} + make && make install + [ ! -e "${python_install_dir}/bin/python" -a -e "${python_install_dir}/bin/python3" ] && ln -s ${python_install_dir}/bin/python{3,} + [ ! -e "${python_install_dir}/bin/pip" -a -e "${python_install_dir}/bin/pip3" ] && ln -s ${python_install_dir}/bin/pip{3,} + popd > /dev/null + fi + + if [ ! -e "${python_install_dir}/bin/pip" ]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/setuptools-${setuptools_ver}.zip && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/pip-${pip_ver}.tar.gz && Download_src + unzip -q setuptools-${setuptools_ver}.zip + tar xzf pip-${pip_ver}.tar.gz + pushd setuptools-${setuptools_ver} > /dev/null + ${python_install_dir}/bin/python setup.py install + popd > /dev/null + pushd pip-${pip_ver} > /dev/null + ${python_install_dir}/bin/python setup.py install + popd > /dev/null + fi + + if [ ! -e "/root/.pip/pip.conf" ] ;then + # get the IP information + PUBLIC_IPADDR=$(../lib/py/get_public_ipaddr.py) + IPADDR_COUNTRY=$(../lib/py/get_ipaddr_state.py ${PUBLIC_IPADDR}) + if [ "${IPADDR_COUNTRY}"x == "CN"x ]; then + [ ! -d "/root/.pip" ] && mkdir /root/.pip + echo -e "[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple" > /root/.pip/pip.conf + fi + fi + + if [ -e "${python_install_dir}/bin/python3" ]; then + echo "${CSUCCESS}Python ${python_ver} installed successfully! ${CEND}" + rm -rf Python-${python_ver} + fi + popd > /dev/null + fi +} + +Uninstall_Python() { + if [ -e "${python_install_dir}/bin/python" ]; then + echo "${CMSG}Python uninstall completed${CEND}" + rm -rf ${python_install_dir} + fi +} diff --git a/modules/php-addons/ZendGuardLoader.sh b/modules/php-addons/ZendGuardLoader.sh new file mode 100644 index 0000000..5100e65 --- /dev/null +++ b/modules/php-addons/ZendGuardLoader.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_ZendGuardLoader() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + [ ! -d "${phpExtensionDir}" ] && mkdir -p ${phpExtensionDir} + if [ -n "`echo $phpExtensionDir | grep 'non-zts'`" ] && [ "${armplatform}" != 'y' ]; then + case "${PHP_main_ver}" in + 5.6) + tar xzf zend-loader-php5.6-linux-x86_64.tar.gz + /bin/mv zend-loader-php5.6-linux-x86_64/ZendGuardLoader.so ${phpExtensionDir} + rm -rf zend-loader-php5.6-linux-x86_64 + ;; + 5.5) + tar xzf zend-loader-php5.5-linux-x86_64.tar.gz + /bin/mv zend-loader-php5.5-linux-x86_64/ZendGuardLoader.so ${phpExtensionDir} + rm -rf zend-loader-php5.5-linux-x86_64 + ;; + 5.4) + tar xzf ZendGuardLoader-70429-PHP-5.4-linux-glibc23-x86_64.tar.gz + /bin/mv ZendGuardLoader-70429-PHP-5.4-linux-glibc23-x86_64/php-5.4.x/ZendGuardLoader.so ${phpExtensionDir} + rm -rf ZendGuardLoader-70429-PHP-5.4-linux-glibc23-x86_64 + ;; + 5.3) + tar xzf ZendGuardLoader-php-5.3-linux-glibc23-x86_64.tar.gz + /bin/mv ZendGuardLoader-php-5.3-linux-glibc23-x86_64/php-5.3.x/ZendGuardLoader.so ${phpExtensionDir} + rm -rf ZendGuardLoader-php-5.3-linux-glibc23-x86_64 + ;; + *) + echo "${CWARNING}Your php ${PHP_detail_ver} does not support ZendGuardLoader! ${CEND}"; + ;; + esac + + if [ -f "${phpExtensionDir}/ZendGuardLoader.so" ]; then + chmod 644 ${phpExtensionDir}/ZendGuardLoader.so + cat > ${php_install_dir}/etc/php.d/01-ZendGuardLoader.ini<< EOF +[Zend Guard Loader] +zend_extension=${phpExtensionDir}/ZendGuardLoader.so +zend_loader.enable=1 +zend_loader.disable_licensing=0 +zend_loader.obfuscation_level_support=3 +EOF + echo "${CSUCCESS}PHP ZendGuardLoader module installed successfully! ${CEND}" + fi + else + echo "Error! Your Apache's prefork or PHP already enable thread safety or platform ${TARGET_ARCH} does not support ZendGuardLoader! " + fi + popd > /dev/null + fi +} + +Uninstall_ZendGuardLoader() { + if [ -e "${php_install_dir}/etc/php.d/01-ZendGuardLoader.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/01-ZendGuardLoader.ini + echo; echo "${CMSG}PHP ZendGuardLoader module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP ZendGuardLoader module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/apcu.sh b/modules/php-addons/apcu.sh new file mode 100644 index 0000000..4454221 --- /dev/null +++ b/modules/php-addons/apcu.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_APCU() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + if [ "`${php_install_dir}/bin/php-config --version | awk -F. '{print $1}'`" == '5' ]; then + tar xzf apcu-${apcu_oldver}.tgz + pushd apcu-${apcu_oldver} > /dev/null + else + tar xzf apcu-${apcu_ver}.tgz + pushd apcu-${apcu_ver} > /dev/null + fi + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + if [ -f "${phpExtensionDir}/apcu.so" ]; then + cat > ${php_install_dir}/etc/php.d/02-apcu.ini << EOF +[apcu] +extension=apcu.so +apc.enabled=1 +apc.shm_size=32M +apc.ttl=7200 +apc.enable_cli=1 +EOF + /bin/cp apc.php ${wwwroot_dir}/default + popd > /dev/null + echo "${CSUCCESS}PHP apcu module installed successfully! ${CEND}" + rm -rf apcu-${apcu_ver} apcu-${apcu_oldver} package.xml + else + echo "${CFAILURE}PHP apcu module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_APCU() { + if [ -e "${php_install_dir}/etc/php.d/02-apcu.ini" ]; then + rm -rf ${php_install_dir}/etc/php.d/02-apcu.ini ${wwwroot_dir}/default/apc.php + echo; echo "${CMSG}PHP apcu module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP apcu module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/composer.sh b/modules/php-addons/composer.sh new file mode 100644 index 0000000..2aa319d --- /dev/null +++ b/modules/php-addons/composer.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_composer() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + if [ -e "/usr/local/bin/composer" ]; then + echo "${CWARNING}PHP Composer already installed! ${CEND}" + else + pushd ${oneinstack_dir}/src > /dev/null + # get the IP information + PUBLIC_IPADDR=$(../lib/py/get_public_ipaddr.py) + IPADDR_COUNTRY=$(../lib/py/get_ipaddr_state.py ${PUBLIC_IPADDR}) + if [ "${IPADDR_COUNTRY}"x == "CN"x ]; then + wget -c https://mirrors.aliyun.com/composer/composer.phar -O /usr/local/bin/composer > /dev/null 2>&1 + ${php_install_dir}/bin/php /usr/local/bin/composer config -g repo.packagist composer https://packagist.phpcomposer.com + else + wget -c https://getcomposer.org/composer.phar -O /usr/local/bin/composer > /dev/null 2>&1 + fi + chmod +x /usr/local/bin/composer + if [ -e "/usr/local/bin/composer" ]; then + echo; echo "${CSUCCESS}PHP Composer installed successfully! ${CEND}" + else + echo; echo "${CFAILURE}PHP Composer install failed, Please try again! ${CEND}" + fi + popd > /dev/null + fi + fi +} + +Uninstall_composer() { + if [ -e "/usr/local/bin/composer" ]; then + rm -f /usr/local/bin/composer + echo; echo "${CMSG}Composer uninstall completed${CEND}"; + else + echo; echo "${CWARNING}Composer does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/eaccelerator.sh b/modules/php-addons/eaccelerator.sh new file mode 100644 index 0000000..22244cb --- /dev/null +++ b/modules/php-addons/eaccelerator.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_eAccelerator() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + if [[ "${PHP_main_ver}" =~ ^5.[3-4]$ ]]; then + if [ "${PHP_main_ver}" == '5.3' ]; then + tar jxf eaccelerator-${eaccelerator_ver}.tar.bz2 + pushd eaccelerator-${eaccelerator_ver} > /dev/null + elif [ "${PHP_main_ver}" == '5.4' ]; then + /bin/mv master eaccelerator-eaccelerator-42067ac.tar.gz + tar xzf eaccelerator-eaccelerator-42067ac.tar.gz + pushd eaccelerator-eaccelerator-42067ac > /dev/null + fi + ${php_install_dir}/bin/phpize + ./configure --enable-eaccelerator=shared --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/eaccelerator.so" ]; then + mkdir /var/eaccelerator_cache;chown -R ${run_user}:${run_group} /var/eaccelerator_cache + cat > ${php_install_dir}/etc/php.d/02-eaccelerator.ini << EOF +[eaccelerator] +zend_extension=${phpExtensionDir}/eaccelerator.so +eaccelerator.shm_size=64 +eaccelerator.cache_dir=/var/eaccelerator_cache +eaccelerator.enable=1 +eaccelerator.optimizer=1 +eaccelerator.check_mtime=1 +eaccelerator.debug=0 +eaccelerator.filter= +eaccelerator.shm_max=0 +eaccelerator.shm_ttl=0 +eaccelerator.shm_prune_period=0 +eaccelerator.shm_only=0 +eaccelerator.compress=0 +eaccelerator.compress_level=9 +eaccelerator.keys=disk_only +eaccelerator.sessions=disk_only +eaccelerator.content=disk_only +EOF + [ -z "$(grep 'kernel.shmmax = 67108864' /etc/sysctl.conf)" ] && echo "kernel.shmmax = 67108864" >> /etc/sysctl.conf + sysctl -p + echo "${CSUCCESS}PHP eaccelerator module installed successfully! ${CEND}" + rm -rf eaccelerator-${eaccelerator_ver} eaccelerator-eaccelerator-42067ac + else + echo "${CFAILURE}PHP eaccelerator module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + echo; echo "${CWARNING}Your php ${PHP_detail_ver} does not support eAccelerator! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_eAccelerator() { + if [ -e "${php_install_dir}/etc/php.d/02-eaccelerator.ini" ]; then + rm -rf ${php_install_dir}/etc/php.d/02-eaccelerator.ini /var/eaccelerator_cache + echo; echo "${CMSG}PHP eaccelerator module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP eaccelerator module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/ioncube.sh b/modules/php-addons/ioncube.sh new file mode 100644 index 0000000..4228eb9 --- /dev/null +++ b/modules/php-addons/ioncube.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_ionCube() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=`${php_install_dir}/bin/php-config --version` + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + [ ! -d "${phpExtensionDir}" ] && mkdir -p ${phpExtensionDir} + [ -e "ioncube_loaders_lin_${SYS_ARCH_i}.tar.gz" ] && tar xzf ioncube_loaders_lin_${SYS_ARCH_i}.tar.gz + if [ -z "`echo ${phpExtensionDir} | grep 'non-zts'`" ]; then + /bin/mv ioncube/ioncube_loader_lin_${PHP_main_ver}_ts.so ${phpExtensionDir} + zend_extension="${phpExtensionDir}/ioncube_loader_lin_${PHP_main_ver}_ts.so" + else + /bin/mv ioncube/ioncube_loader_lin_${PHP_main_ver}.so ${phpExtensionDir} + zend_extension="${phpExtensionDir}/ioncube_loader_lin_${PHP_main_ver}.so" + fi + + if [ -f "${zend_extension}" ]; then + echo "zend_extension=${zend_extension}" > ${php_install_dir}/etc/php.d/00-ioncube.ini + echo "${CSUCCESS}PHP ionCube module installed successfully! ${CEND}" + rm -rf ioncube + fi + popd > /dev/null + fi +} + +Uninstall_ionCube() { + if [ -e "${php_install_dir}/etc/php.d/00-ioncube.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/00-ioncube.ini + echo; echo "${CMSG}PHP ionCube module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP ionCube module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_calendar.sh b/modules/php-addons/pecl_calendar.sh new file mode 100644 index 0000000..082abb5 --- /dev/null +++ b/modules/php-addons/pecl_calendar.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_calendar() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + src_url=https://secure.php.net/distributions/php-${PHP_detail_ver}.tar.gz && Download_src + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/calendar > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/calendar.so" ]; then + echo 'extension=calendar.so' > ${php_install_dir}/etc/php.d/04-calendar.ini + echo "${CSUCCESS}PHP calendar module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP calendar module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_calendar() { + if [ -e "${php_install_dir}/etc/php.d/04-calendar.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-calendar.ini + echo; echo "${CMSG}PHP calendar module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP calendar module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_fileinfo.sh b/modules/php-addons/pecl_fileinfo.sh new file mode 100644 index 0000000..a3d6073 --- /dev/null +++ b/modules/php-addons/pecl_fileinfo.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_fileinfo() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + src_url=https://secure.php.net/distributions/php-${PHP_detail_ver}.tar.gz && Download_src + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/fileinfo > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + [[ "${php_option}" =~ ^[23]$ ]] && sed -i 's@^CFLAGS = -g -O2@CFLAGS = -std=c99 -g -O2@' Makefile + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/fileinfo.so" ]; then + echo 'extension=fileinfo.so' > ${php_install_dir}/etc/php.d/04-fileinfo.ini + echo "${CSUCCESS}PHP fileinfo module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP fileinfo module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_fileinfo() { + if [ -e "${php_install_dir}/etc/php.d/04-fileinfo.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-fileinfo.ini + echo; echo "${CMSG}PHP fileinfo module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP fileinfo module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_imap.sh b/modules/php-addons/pecl_imap.sh new file mode 100644 index 0000000..0bfcf31 --- /dev/null +++ b/modules/php-addons/pecl_imap.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_imap() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + if [ "${PM}" == 'yum' ]; then + yum -y install libc-client-devel + [ ! -e /usr/lib/libc-client.so ] && ln -s /usr/lib64/libc-client.so /usr/lib/libc-client.so + else + apt-get -y install libc-client2007e-dev + fi + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + src_url=https://secure.php.net/distributions/php-${PHP_detail_ver}.tar.gz && Download_src + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/imap > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --with-kerberos --with-imap --with-imap-ssl + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/imap.so" ]; then + echo 'extension=imap.so' > ${php_install_dir}/etc/php.d/04-imap.ini + echo "${CSUCCESS}PHP imap module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP imap module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_imap() { + if [ -e "${php_install_dir}/etc/php.d/04-imap.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-imap.ini + echo; echo "${CMSG}PHP imap module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP imap module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_ldap.sh b/modules/php-addons/pecl_ldap.sh new file mode 100644 index 0000000..9baf9db --- /dev/null +++ b/modules/php-addons/pecl_ldap.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_ldap() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + src_url=https://secure.php.net/distributions/php-${PHP_detail_ver}.tar.gz && Download_src + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/ldap > /dev/null + if [ "${PM}" == 'yum' ]; then + yum -y install openldap-devel + else + apt-get -y install libldap2-dev + ln -s /usr/lib/${ARCH}-linux-gnu/libldap.so /usr/lib/ + ln -s /usr/lib/${ARCH}-linux-gnu/liblber.so /usr/lib/ + fi + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --with-ldap --with-libdir=lib64 + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/ldap.so" ]; then + echo 'extension=ldap.so' > ${php_install_dir}/etc/php.d/04-ldap.ini + echo "${CSUCCESS}PHP ldap module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP ldap module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_ldap() { + if [ -e "${php_install_dir}/etc/php.d/04-ldap.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-ldap.ini + echo; echo "${CMSG}PHP ldap module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP ldap module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_mongodb.sh b/modules/php-addons/pecl_mongodb.sh new file mode 100644 index 0000000..a969419 --- /dev/null +++ b/modules/php-addons/pecl_mongodb.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_mongodb() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + if [[ "$(${php_install_dir}/bin/php-config --version | awk -F. '{print $1$2}')" =~ ^5[3-4]$ ]]; then + src_url=https://pecl.php.net/get/mongo-${pecl_mongo_ver}.tgz && Download_src + tar xzf mongo-${pecl_mongo_ver}.tgz + pushd mongo-${pecl_mongo_ver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/mongo.so" ]; then + echo 'extension=mongo.so' > ${php_install_dir}/etc/php.d/07-mongo.ini + rm -rf mongo-${pecl_mongo_ver} + echo "${CSUCCESS}PHP mongo module installed successfully! ${CEND}" + else + echo "${CFAILURE}PHP mongo module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + if [[ "$(${php_install_dir}/bin/php-config --version | awk -F. '{print $1$2}')" =~ ^7[0-2]$ ]]; then + src_url=https://pecl.php.net/get/mongodb-${pecl_mongodb_oldver}.tgz && Download_src + tar xzf mongodb-${pecl_mongodb_oldver}.tgz + pushd mongodb-${pecl_mongodb_oldver} > /dev/null + else + src_url=https://pecl.php.net/get/mongodb-${pecl_mongodb_ver}.tgz && Download_src + tar xzf mongodb-${pecl_mongodb_ver}.tgz + pushd mongodb-${pecl_mongodb_ver} > /dev/null + fi + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/mongodb.so" ]; then + echo 'extension=mongodb.so' > ${php_install_dir}/etc/php.d/07-mongodb.ini + echo "${CSUCCESS}PHP mongodb module installed successfully! ${CEND}" + rm -rf mongodb-${pecl_mongodb_oldver} mongodb-${pecl_mongodb_ver} + else + echo "${CFAILURE}PHP mongodb module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + fi + popd > /dev/null + fi +} + +Uninstall_pecl_mongodb() { + if [ -e "${php_install_dir}/etc/php.d/07-mongo.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/07-mongo.ini + echo; echo "${CMSG}PHP mongo module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP mongo module does not exist! ${CEND}" + fi + if [ -e "${php_install_dir}/etc/php.d/07-mongodb.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/07-mongodb.ini + echo; echo "${CMSG}PHP mongodb module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP mongodb module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_pgsql.sh b/modules/php-addons/pecl_pgsql.sh new file mode 100644 index 0000000..e6b9f36 --- /dev/null +++ b/modules/php-addons/pecl_pgsql.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_pgsql() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/pgsql > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-pgsql=${pgsql_install_dir} --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + pushd php-${PHP_detail_ver}/ext/pdo_pgsql > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-pdo-pgsql=${pgsql_install_dir} --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/pgsql.so" -a -f "${phpExtensionDir}/pdo_pgsql.so" ]; then + echo 'extension=pgsql.so' > ${php_install_dir}/etc/php.d/07-pgsql.ini + echo 'extension=pdo_pgsql.so' >> ${php_install_dir}/etc/php.d/07-pgsql.ini + echo "${CSUCCESS}PHP pgsql module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP pgsql module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_pgsql() { + if [ -e "${php_install_dir}/etc/php.d/07-pgsql.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/07-pgsql.ini + echo; echo "${CMSG}PHP pgsql module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP pgsql module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_phalcon.sh b/modules/php-addons/pecl_phalcon.sh new file mode 100644 index 0000000..fd9fa83 --- /dev/null +++ b/modules/php-addons/pecl_phalcon.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_phalcon() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + if [[ "${PHP_main_ver}" =~ ^7.[2-4]$|^8.0$ ]]; then + src_url=https://pecl.php.net/get/phalcon-${phalcon_ver}.tgz && Download_src + tar xzf phalcon-${phalcon_ver}.tgz + pushd phalcon-${phalcon_ver} > /dev/null + ${php_install_dir}/bin/phpize + echo "${CMSG}It may take a few minutes... ${CEND}" + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + elif [[ "${PHP_main_ver}" =~ ^5.[5-6]$|^7.[0-1]$ ]]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/cphalcon-${phalcon_oldver}.tar.gz && Download_src + tar xzf cphalcon-${phalcon_oldver}.tar.gz + pushd cphalcon-${phalcon_oldver}/build > /dev/null + echo "${CMSG}It may take a few minutes... ${CEND}" + ./install --phpize ${php_install_dir}/bin/phpize --php-config ${php_install_dir}/bin/php-config --arch 64bits + popd > /dev/null + else + echo "${CWARNING}Your php ${PHP_detail_ver} does not support phalcon! ${CEND}" + fi + if [ -f "${phpExtensionDir}/phalcon.so" ]; then + echo 'extension=phalcon.so' > ${php_install_dir}/etc/php.d/04-phalcon.ini + echo "${CSUCCESS}PHP phalcon module installed successfully! ${CEND}" + rm -rf cphalcon-${phalcon_oldver} phalcon-${phalcon_ver} + else + echo "${CFAILURE}PHP phalcon module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_phalcon() { + if [ -e "${php_install_dir}/etc/php.d/04-phalcon.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-phalcon.ini + echo; echo "${CMSG}PHP phalcon module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP phalcon module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_swoole.sh b/modules/php-addons/pecl_swoole.sh new file mode 100644 index 0000000..35e20c6 --- /dev/null +++ b/modules/php-addons/pecl_swoole.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_swoole() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^5.[3-6]$ ]]; then + src_url=https://pecl.php.net/get/swoole-1.10.5.tgz && Download_src + tar xzf swoole-1.10.5.tgz + pushd swoole-1.10.5 > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --enable-openssl --with-openssl-dir=${openssl_install_dir} + elif [[ "${PHP_main_ver}" =~ ^7.[0-1]$ ]]; then + src_url=https://pecl.php.net/get/swoole-${swoole_oldver}.tgz && Download_src + tar xzf swoole-${swoole_oldver}.tgz + pushd swoole-${swoole_oldver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --enable-openssl --with-openssl-dir=${openssl_install_dir} + else + src_url=https://pecl.php.net/get/swoole-${swoole_ver}.tgz && Download_src + tar xzf swoole-${swoole_ver}.tgz + pushd swoole-${swoole_ver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --enable-openssl --with-openssl-dir=${openssl_install_dir} --enable-http2 --enable-swoole-json --enable-swoole-curl + fi + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/swoole.so" ]; then + echo 'extension=swoole.so' > ${php_install_dir}/etc/php.d/06-swoole.ini + echo "${CSUCCESS}PHP swoole module installed successfully! ${CEND}" + rm -rf swoole-${swoole_ver} swoole-${swoole_oldver} + else + echo "${CFAILURE}PHP swoole module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_pecl_swoole() { + if [ -e "${php_install_dir}/etc/php.d/06-swoole.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/06-swoole.ini + echo; echo "${CMSG}PHP swoole module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP swoole module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_xdebug.sh b/modules/php-addons/pecl_xdebug.sh new file mode 100644 index 0000000..d24d094 --- /dev/null +++ b/modules/php-addons/pecl_xdebug.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_xdebug() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^7.[0-4]$|^80$ ]]; then + if [[ "${PHP_main_ver}" =~ ^7.[0-1]$ ]]; then + src_url=https://pecl.php.net/get/xdebug-${xdebug_oldver}.tgz && Download_src + tar xzf xdebug-${xdebug_oldver}.tgz + pushd xdebug-${xdebug_oldver} > /dev/null + else + src_url=https://pecl.php.net/get/xdebug-${xdebug_ver}.tgz && Download_src + tar xzf xdebug-${xdebug_ver}.tgz + pushd xdebug-${xdebug_ver} > /dev/null + fi + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/xdebug.so" ]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/webgrind-master.zip && Download_src + unzip -q webgrind-master.zip + /bin/mv webgrind-master ${wwwroot_dir}/default/webgrind + [ ! -e /tmp/xdebug ] && { mkdir /tmp/xdebug; chown ${run_user}:${run_group} /tmp/xdebug; } + [ ! -e /tmp/webgrind ] && { mkdir /tmp/webgrind; chown ${run_user}:${run_group} /tmp/webgrind; } + chown -R ${run_user}:${run_group} ${wwwroot_dir}/default/webgrind + sed -i 's@static $storageDir.*@static $storageDir = "/tmp/webgrind";@' ${wwwroot_dir}/default/webgrind/config.php + sed -i 's@static $profilerDir.*@static $profilerDir = "/tmp/xdebug";@' ${wwwroot_dir}/default/webgrind/config.php + cat > ${php_install_dir}/etc/php.d/08-xdebug.ini << EOF +[xdebug] +zend_extension=xdebug.so +xdebug.trace_output_dir=/tmp/xdebug +xdebug.profiler_output_dir = /tmp/xdebug +xdebug.profiler_enable = On +xdebug.profiler_enable_trigger = 1 +EOF + echo "${CSUCCESS}PHP xdebug module installed successfully! ${CEND}" + echo; echo "Webgrind URL: ${CMSG}http://{Public IP}/webgrind ${CEND}" + rm -rf xdebug-${xdebug_ver} xdebug-${xdebug_oldver} + else + echo "${CFAILURE}PHP xdebug module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + echo "${CWARNING}Your php ${PHP_detail_ver} does not support xdebug! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_pecl_xdebug() { + if [ -e "${php_install_dir}/etc/php.d/08-xdebug.ini" ]; then + rm -rf ${php_install_dir}/etc/php.d/08-xdebug.ini /tmp/{xdebug,webgrind} ${wwwroot_dir}/default/webgrind + echo; echo "${CMSG}PHP xdebug module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP xdebug module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_yaf.sh b/modules/php-addons/pecl_yaf.sh new file mode 100644 index 0000000..524e057 --- /dev/null +++ b/modules/php-addons/pecl_yaf.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_yaf() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^7.[0-4]$|^8.0$ ]]; then + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + src_url=https://pecl.php.net/get/yaf-${yaf_ver}.tgz && Download_src + tar xzf yaf-${yaf_ver}.tgz + pushd yaf-${yaf_ver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/yaf.so" ]; then + echo 'extension=yaf.so' > ${php_install_dir}/etc/php.d/04-yaf.ini + echo "${CSUCCESS}PHP yaf module installed successfully! ${CEND}" + rm -rf yaf-${yaf_ver} + else + echo "${CFAILURE}PHP yaf module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + echo "${CWARNING}Your php ${PHP_detail_ver} does not support yaf! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_pecl_yaf() { + if [ -e "${php_install_dir}/etc/php.d/04-yaf.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-yaf.ini + echo; echo "${CMSG}PHP yaf module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP yaf module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/pecl_yar.sh b/modules/php-addons/pecl_yar.sh new file mode 100644 index 0000000..986a0ef --- /dev/null +++ b/modules/php-addons/pecl_yar.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_pecl_yar() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^7.[0-4]$|^8.0$ ]]; then + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + src_url=https://pecl.php.net/get/yar-${yar_ver}.tgz && Download_src + tar xzf yar-${yar_ver}.tgz + pushd yar-${yar_ver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config --with-curl=${curl_install_dir} + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/yar.so" ]; then + echo 'extension=yar.so' > ${php_install_dir}/etc/php.d/04-yar.ini + echo "${CSUCCESS}PHP yar module installed successfully! ${CEND}" + rm -rf yar-${yar_ver} + else + echo "${CFAILURE}PHP yar module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + echo "${CWARNING}Your php ${PHP_detail_ver} does not support yar! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_pecl_yar() { + if [ -e "${php_install_dir}/etc/php.d/04-yar.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/04-yar.ini + echo; echo "${CMSG}PHP yar module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP yar module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/sourceguardian.sh b/modules/php-addons/sourceguardian.sh new file mode 100644 index 0000000..06ea553 --- /dev/null +++ b/modules/php-addons/sourceguardian.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_SourceGuardian() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + PHP_detail_ver=`${php_install_dir}/bin/php-config --version` + PHP_main_ver=${PHP_detail_ver%.*} + phpExtensionDir=`${php_install_dir}/bin/php-config --extension-dir` + [ ! -e sourceguardian ] && mkdir sourceguardian + [ -e "loaders.linux-${ARCH}.tar.gz" ] && tar xzf loaders.linux-${ARCH}.tar.gz -C sourceguardian + + if [ -e "sourceguardian/ixed.${PHP_main_ver}.lin" ]; then + [ ! -d "${phpExtensionDir}" ] && mkdir -p ${phpExtensionDir} + if [ -z "`echo ${phpExtensionDir} | grep 'non-zts'`" ]; then + /bin/mv sourceguardian/ixed.${PHP_main_ver}ts.lin ${phpExtensionDir} + extension="ixed.${PHP_main_ver}ts.lin" + else + /bin/mv sourceguardian/ixed.${PHP_main_ver}.lin ${phpExtensionDir} + extension="ixed.${PHP_main_ver}.lin" + fi + + if [ -f "${phpExtensionDir}/ixed.${PHP_main_ver}.lin" ]; then + echo "extension=${extension}" > ${php_install_dir}/etc/php.d/02-sourceguardian.ini + echo "${CSUCCESS}PHP SourceGuardian module installed successfully! ${CEND}" + rm -rf sourceguardian + fi + else + echo; echo "${CWARNING}Your php ${PHP_detail_ver} or platform ${TARGET_ARCH} does not support SourceGuardian! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_SourceGuardian() { + if [ -e "${php_install_dir}/etc/php.d/02-sourceguardian.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/02-sourceguardian.ini + echo; echo "${CMSG}PHP SourceGuardian module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP SourceGuardian module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/xcache.sh b/modules/php-addons/xcache.sh new file mode 100644 index 0000000..f892e44 --- /dev/null +++ b/modules/php-addons/xcache.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_XCache() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^5.[3-6]$ ]]; then + tar xzf xcache-${xcache_ver}.tar.gz + pushd xcache-${xcache_ver} > /dev/null + ${php_install_dir}/bin/phpize + ./configure --enable-xcache --enable-xcache-coverager --enable-xcache-optimizer --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + if [ -f "${phpExtensionDir}/xcache.so" ]; then + /bin/cp -R htdocs ${wwwroot_dir}/default/xcache + popd > /dev/null + chown -R ${run_user}:${run_group} ${wwwroot_dir}/default/xcache + touch /tmp/xcache;chown ${run_user}:${run_group} /tmp/xcache + let xcacheCount="${CPU}+1" + let xcacheSize="${Memory_limit}/2" + cat > ${php_install_dir}/etc/php.d/04-xcache.ini << EOF +[xcache-common] +extension=xcache.so +[xcache.admin] +xcache.admin.enable_auth=On +xcache.admin.user=admin +xcache.admin.pass="${xcachepwd_md5}" + +[xcache] +xcache.size=${xcacheSize}M +xcache.count=${xcacheCount} +xcache.slots=8K +xcache.ttl=3600 +xcache.gc_interval=300 +xcache.var_size=4M +xcache.var_count=${xcacheCount} +xcache.var_slots=8K +xcache.var_ttl=0 +xcache.var_maxttl=0 +xcache.var_gc_interval=300 +xcache.test=Off +xcache.readonly_protection=Off +xcache.shm_scheme=mmap +xcache.mmap_path=/tmp/xcache +xcache.coredump_directory= +xcache.cacher=On +xcache.stat=On +xcache.optimizer=Off + +[xcache.coverager] +; enabling this feature will impact performance +; enable only if xcache.coverager == On && xcache.coveragedump_directory == "non-empty-value" +; enable coverage data collecting and xcache_coverager_start/stop/get/clean() functions +xcache.coverager = Off +xcache.coverager_autostart = On +xcache.coveragedump_directory = "" +EOF + echo "${CSUCCESS}PHP xcache module installed successfully! ${CEND}" + rm -rf xcache-${xcache_ver} + else + echo "${CFAILURE}PHP xcache module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + else + echo; echo "${CWARNING}Your php ${PHP_detail_ver} does not support XCache! ${CEND}"; + fi + popd > /dev/null + fi +} + +Uninstall_XCache() { + if [ -e "${php_install_dir}/etc/php.d/04-xcache.ini" ]; then + rm -rf ${php_install_dir}/etc/php.d/04-xcache.ini ${wwwroot_dir}/default/xcache /tmp/xcache + echo; echo "${CMSG}PHP xcache module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP xcache module does not exist! ${CEND}" + fi +} diff --git a/modules/php-addons/zendopcache.sh b/modules/php-addons/zendopcache.sh new file mode 100644 index 0000000..f908b8b --- /dev/null +++ b/modules/php-addons/zendopcache.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_ZendOPcache() { + if [ -e "${php_install_dir}/bin/phpize" ]; then + pushd ${oneinstack_dir}/src > /dev/null + phpExtensionDir=$(${php_install_dir}/bin/php-config --extension-dir) + PHP_detail_ver=$(${php_install_dir}/bin/php-config --version) + PHP_main_ver=${PHP_detail_ver%.*} + if [[ "${PHP_main_ver}" =~ ^5.[3-4]$ ]]; then + tar xzf zendopcache-${zendopcache_ver}.tgz + pushd zendopcache-${zendopcache_ver} > /dev/null + else + src_url=https://secure.php.net/distributions/php-${PHP_detail_ver}.tar.gz && Download_src + tar xzf php-${PHP_detail_ver}.tar.gz + pushd php-${PHP_detail_ver}/ext/opcache > /dev/null + fi + + ${php_install_dir}/bin/phpize + ./configure --with-php-config=${php_install_dir}/bin/php-config + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "${phpExtensionDir}/opcache.so" ]; then + # write opcache configs + if [[ "${PHP_main_ver}" =~ ^5.[3-4]$ ]]; then + # For php 5.3 5.4 + cat > ${php_install_dir}/etc/php.d/02-opcache.ini << EOF +[opcache] +zend_extension=${phpExtensionDir}/opcache.so +opcache.enable=1 +opcache.memory_consumption=${Memory_limit} +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=4000 +opcache.revalidate_freq=60 +;opcache.save_comments=0 +opcache.fast_shutdown=1 +opcache.enable_cli=1 +;opcache.optimization_level=0 +EOF + rm -rf zendopcache-${zendopcache_ver} + else + # For php 5.5+ + cat > ${php_install_dir}/etc/php.d/02-opcache.ini << EOF +[opcache] +zend_extension=opcache.so +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=${Memory_limit} +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=100000 +opcache.max_wasted_percentage=5 +opcache.use_cwd=1 +opcache.validate_timestamps=1 +opcache.revalidate_freq=60 +;opcache.save_comments=0 +opcache.fast_shutdown=1 +opcache.consistency_checks=0 +;opcache.optimization_level=0 +EOF + fi + + echo "${CSUCCESS}PHP opcache module installed successfully! ${CEND}" + rm -rf php-${PHP_detail_ver} + else + echo "${CFAILURE}PHP opcache module install failed, Please contact the author! ${CEND}" && lsb_release -a + fi + popd > /dev/null + fi +} + +Uninstall_ZendOPcache() { + if [ -e "${php_install_dir}/etc/php.d/02-opcache.ini" ]; then + rm -f ${php_install_dir}/etc/php.d/02-opcache.ini + echo; echo "${CMSG}PHP opcache module uninstall completed${CEND}" + else + echo; echo "${CWARNING}PHP opcache module does not exist! ${CEND}" + fi +} diff --git a/modules/php/mphp.sh b/modules/php/mphp.sh new file mode 100644 index 0000000..c8703eb --- /dev/null +++ b/modules/php/mphp.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_MPHP() { + if [ -e "${php_install_dir}/sbin/php-fpm" ]; then + if [ -e "${php_install_dir}${mphp_ver}/bin/phpize" ]; then + echo "${CWARNING}PHP${mphp_ver} already installed! ${CEND}" + else + [ -e "/lib/systemd/system/php-fpm.service" ] && /bin/mv /lib/systemd/system/php-fpm.service{,_bk} + php_install_dir=${php_install_dir}${mphp_ver} + case "${mphp_ver}" in + 74) + . modules/php/php-7.4.sh + Install_PHP74 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + ;; + 80) + . modules/php/php-8.0.sh + Install_PHP80 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + ;; + 81) + . modules/php/php-8.1.sh + Install_PHP81 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log + ;; + esac + if [ -e "${php_install_dir}/sbin/php-fpm" ]; then + systemctl stop php-fpm + sed -i "s@/dev/shm/php-cgi.sock@/dev/shm/php${mphp_ver}-cgi.sock@" ${php_install_dir}/etc/php-fpm.conf + [ -e "/lib/systemd/system/php-fpm.service" ] && /bin/mv /lib/systemd/system/php-fpm.service /lib/systemd/system/php${mphp_ver}-fpm.service + [ -e "/lib/systemd/system/php-fpm.service_bk" ] && /bin/mv /lib/systemd/system/php-fpm.service{_bk,} + systemctl enable php${mphp_ver}-fpm + systemctl enable php-fpm + systemctl start php-fpm + systemctl start php${mphp_ver}-fpm + sed -i "s@${php_install_dir}/bin:@@" /etc/profile + fi + fi + else + echo "${CWARNING}To use the multiple PHP versions, You need to use PHP-FPM! ${CEND}" + fi +} diff --git a/modules/php/php-7.4.sh b/modules/php/php-7.4.sh new file mode 100644 index 0000000..d7183b6 --- /dev/null +++ b/modules/php/php-7.4.sh @@ -0,0 +1,278 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_PHP74() { + pushd ${oneinstack_dir}/src > /dev/null + if [ ! -e "/usr/local/lib/libiconv.la" ]; then + tar xzf libiconv-${libiconv_ver}.tar.gz + pushd libiconv-${libiconv_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libiconv-${libiconv_ver} + fi + + if [ ! -e "${curl_install_dir}/lib/libcurl.la" ]; then + tar xzf curl-${curl_ver}.tar.gz + pushd curl-${curl_ver} > /dev/null + ./configure --prefix=${curl_install_dir} ${php74_with_ssl} + make -j ${THREAD} && make install + popd > /dev/null + rm -rf curl-${curl_ver} + fi + + if [ ! -e "${freetype_install_dir}/lib/libfreetype.la" ]; then + tar xzf freetype-${freetype_ver}.tar.gz + pushd freetype-${freetype_ver} > /dev/null + ./configure --prefix=${freetype_install_dir} --enable-freetype-config + make -j ${THREAD} && make install + ln -sf ${freetype_install_dir}/include/freetype2/* /usr/include/ + [ -d /usr/lib/pkgconfig ] && /bin/cp ${freetype_install_dir}/lib/pkgconfig/freetype2.pc /usr/lib/pkgconfig/ + popd > /dev/null + rm -rf freetype-${freetype_ver} + fi + + if [ ! -e "/usr/local/lib/pkgconfig/libargon2.pc" ]; then + tar xzf argon2-${argon2_ver}.tar.gz + pushd argon2-${argon2_ver} > /dev/null + make -j ${THREAD} && make install + [ ! -d /usr/local/lib/pkgconfig ] && mkdir -p /usr/local/lib/pkgconfig + /bin/cp libargon2.pc /usr/local/lib/pkgconfig/ + popd > /dev/null + rm -rf argon2-${argon2_ver} + fi + + if [ ! -e "/usr/local/lib/libsodium.la" ]; then + tar xzf libsodium-${libsodium_ver}.tar.gz + pushd libsodium-${libsodium_ver} > /dev/null + ./configure --disable-dependency-tracking --enable-minimal + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libsodium-${libsodium_ver} + fi + + if [ ! -e "/usr/local/lib/libzip.la" ]; then + tar xzf libzip-${libzip_ver}.tar.gz + pushd libzip-${libzip_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libzip-${libzip_ver} + fi + + if [ ! -e "/usr/local/include/mhash.h" -a ! -e "/usr/include/mhash.h" ]; then + tar xzf mhash-${mhash_ver}.tar.gz + pushd mhash-${mhash_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf mhash-${mhash_ver} + fi + + [ -z "`grep /usr/local/lib /etc/ld.so.conf.d/*.conf`" ] && echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf + ldconfig + + if [ "${PM}" == 'yum' ]; then + [ ! -e "/lib64/libpcre.so.1" ] && ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1 + [ ! -e "/usr/lib/libc-client.so" ] && ln -s /usr/lib64/libc-client.so /usr/lib/libc-client.so + fi + + id -g ${run_group} >/dev/null 2>&1 + [ $? -ne 0 ] && groupadd ${run_group} + id -u ${run_user} >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -g ${run_group} -M -s /sbin/nologin ${run_user} + + # PHP enables the sqlite3 extension by default; its configure step fails with + # "Package 'sqlite3' not found" when libsqlite3-dev is missing. Install it on + # demand so a skipped/partial dependency stage cannot break the PHP build. + if ! pkg-config --exists sqlite3 >/dev/null 2>&1; then + echo "${CMSG}Installing libsqlite3-dev (required by PHP sqlite3 extension)...${CEND}" + apt-get -y install libsqlite3-dev + fi + + tar xzf php-${php74_ver}.tar.gz + pushd php-${php74_ver} > /dev/null + if [ -e ext/openssl/openssl.c ] && ! grep -Eqi '^#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c; then + sed -i '/OPENSSL_SSLV23_PADDING/i#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c + sed -i '/OPENSSL_SSLV23_PADDING/a#endif' ext/openssl/openssl.c + fi + make clean + # Include the self-built curl's pkgconfig dir so PHP's pkg-config based + # ext/curl detection (PKG_CHECK_MODULES libcurl) can find libcurl.pc. + export PKG_CONFIG_PATH=${curl_install_dir}/lib/pkgconfig/:/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH + # PHP ext/curl uses pkg-config to locate libcurl; if it still can't be found + # (self-built curl .pc missing), fall back to the system dev package. + if ! pkg-config --exists libcurl >/dev/null 2>&1; then + echo "${CMSG}libcurl.pc not found, installing libcurl4-openssl-dev...${CEND}" + apt-get -y install libcurl4-openssl-dev + fi + [ ! -d "${php_install_dir}" ] && mkdir -p ${php_install_dir} + [ "${phpcache_option}" == '1' ] && phpcache_arg='--enable-opcache' || phpcache_arg='--disable-opcache' + ./configure --prefix=${php_install_dir} --with-config-file-path=${php_install_dir}/etc \ + --with-config-file-scan-dir=${php_install_dir}/etc/php.d \ + --with-fpm-user=${run_user} --with-fpm-group=${run_group} --enable-fpm ${phpcache_arg} --disable-fileinfo \ + --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \ + --with-iconv-dir=/usr/local --with-freetype --with-jpeg --with-zlib \ + --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-exif \ + --enable-sysvsem --enable-inline-optimization ${php74_with_curl} --enable-mbregex \ + --enable-mbstring --with-password-argon2 --with-sodium=/usr/local --enable-gd ${php74_with_openssl} \ + --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-ftp --enable-intl --with-xsl \ + --with-gettext --with-zip=/usr/local --enable-soap --disable-debug ${php_modules_options} + make ZEND_EXTRA_LIBS='-liconv' -j ${THREAD} + make install + + if [ -e "${php_install_dir}/bin/phpize" ]; then + [ ! -e "${php_install_dir}/etc/php.d" ] && mkdir -p ${php_install_dir}/etc/php.d + echo "${CSUCCESS}PHP installed successfully! ${CEND}" + else + rm -rf ${php_install_dir} + echo "${CFAILURE}PHP install failed, Please Contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + + [ -z "`grep ^'export PATH=' /etc/profile`" ] && echo "export PATH=${php_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "`grep ^'export PATH=' /etc/profile`" -a -z "`grep ${php_install_dir} /etc/profile`" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${php_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + # wget -c http://pear.php.net/go-pear.phar + # ${php_install_dir}/bin/php go-pear.phar + + /bin/cp php.ini-production ${php_install_dir}/etc/php.ini + + sed -i "s@^memory_limit.*@memory_limit = ${Memory_limit}M@" ${php_install_dir}/etc/php.ini + sed -i 's@^output_buffering =@output_buffering = On\noutput_buffering =@' ${php_install_dir}/etc/php.ini + #sed -i 's@^;cgi.fix_pathinfo.*@cgi.fix_pathinfo=0@' ${php_install_dir}/etc/php.ini + sed -i 's@^short_open_tag = Off@short_open_tag = On@' ${php_install_dir}/etc/php.ini + sed -i 's@^expose_php = On@expose_php = Off@' ${php_install_dir}/etc/php.ini + sed -i 's@^request_order.*@request_order = "CGP"@' ${php_install_dir}/etc/php.ini + sed -i "s@^;date.timezone.*@date.timezone = ${timezone}@" ${php_install_dir}/etc/php.ini + sed -i 's@^post_max_size.*@post_max_size = 100M@' ${php_install_dir}/etc/php.ini + sed -i 's@^upload_max_filesize.*@upload_max_filesize = 50M@' ${php_install_dir}/etc/php.ini + sed -i 's@^max_execution_time.*@max_execution_time = 600@' ${php_install_dir}/etc/php.ini + sed -i 's@^;realpath_cache_size.*@realpath_cache_size = 2M@' ${php_install_dir}/etc/php.ini + sed -i 's@^disable_functions.*@disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen@' ${php_install_dir}/etc/php.ini + [ -e /usr/sbin/sendmail ] && sed -i 's@^;sendmail_path.*@sendmail_path = /usr/sbin/sendmail -t -i@' ${php_install_dir}/etc/php.ini + if [ "${with_old_openssl_flag}" = 'y' ]; then + sed -i "s@^;curl.cainfo.*@curl.cainfo = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.cafile.*@openssl.cafile = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.capath.*@openssl.capath = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + fi + + [ "${phpcache_option}" == '1' ] && cat > ${php_install_dir}/etc/php.d/02-opcache.ini << EOF +[opcache] +zend_extension=opcache.so +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=${Memory_limit} +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=100000 +opcache.max_wasted_percentage=5 +opcache.use_cwd=1 +opcache.validate_timestamps=1 +opcache.revalidate_freq=60 +;opcache.save_comments=0 +opcache.consistency_checks=0 +;opcache.optimization_level=0 +EOF + + # php-fpm Init Script + /bin/cp ${oneinstack_dir}/services/php-fpm.service /lib/systemd/system/ + sed -i "s@/usr/local/php@${php_install_dir}@g" /lib/systemd/system/php-fpm.service + systemctl enable php-fpm + + cat > ${php_install_dir}/etc/php-fpm.conf < /dev/null + [ -e "${php_install_dir}/bin/phpize" ] && rm -rf php-${php74_ver} + popd > /dev/null +} diff --git a/modules/php/php-8.0.sh b/modules/php/php-8.0.sh new file mode 100644 index 0000000..884d796 --- /dev/null +++ b/modules/php/php-8.0.sh @@ -0,0 +1,278 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_PHP80() { + pushd ${oneinstack_dir}/src > /dev/null + if [ ! -e "/usr/local/lib/libiconv.la" ]; then + tar xzf libiconv-${libiconv_ver}.tar.gz + pushd libiconv-${libiconv_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libiconv-${libiconv_ver} + fi + + if [ ! -e "${curl_install_dir}/lib/libcurl.la" ]; then + tar xzf curl-${curl_ver}.tar.gz + pushd curl-${curl_ver} > /dev/null + ./configure --prefix=${curl_install_dir} ${php80_with_ssl} + make -j ${THREAD} && make install + popd > /dev/null + rm -rf curl-${curl_ver} + fi + + if [ ! -e "${freetype_install_dir}/lib/libfreetype.la" ]; then + tar xzf freetype-${freetype_ver}.tar.gz + pushd freetype-${freetype_ver} > /dev/null + ./configure --prefix=${freetype_install_dir} --enable-freetype-config + make -j ${THREAD} && make install + ln -sf ${freetype_install_dir}/include/freetype2/* /usr/include/ + [ -d /usr/lib/pkgconfig ] && /bin/cp ${freetype_install_dir}/lib/pkgconfig/freetype2.pc /usr/lib/pkgconfig/ + popd > /dev/null + rm -rf freetype-${freetype_ver} + fi + + if [ ! -e "/usr/local/lib/pkgconfig/libargon2.pc" ]; then + tar xzf argon2-${argon2_ver}.tar.gz + pushd argon2-${argon2_ver} > /dev/null + make -j ${THREAD} && make install + [ ! -d /usr/local/lib/pkgconfig ] && mkdir -p /usr/local/lib/pkgconfig + /bin/cp libargon2.pc /usr/local/lib/pkgconfig/ + popd > /dev/null + rm -rf argon2-${argon2_ver} + fi + + if [ ! -e "/usr/local/lib/libsodium.la" ]; then + tar xzf libsodium-${libsodium_ver}.tar.gz + pushd libsodium-${libsodium_ver} > /dev/null + ./configure --disable-dependency-tracking --enable-minimal + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libsodium-${libsodium_ver} + fi + + if [ ! -e "/usr/local/lib/libzip.la" ]; then + tar xzf libzip-${libzip_ver}.tar.gz + pushd libzip-${libzip_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libzip-${libzip_ver} + fi + + if [ ! -e "/usr/local/include/mhash.h" -a ! -e "/usr/include/mhash.h" ]; then + tar xzf mhash-${mhash_ver}.tar.gz + pushd mhash-${mhash_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf mhash-${mhash_ver} + fi + + [ -z "`grep /usr/local/lib /etc/ld.so.conf.d/*.conf`" ] && echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf + ldconfig + + if [ "${PM}" == 'yum' ]; then + [ ! -e "/lib64/libpcre.so.1" ] && ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1 + [ ! -e "/usr/lib/libc-client.so" ] && ln -s /usr/lib64/libc-client.so /usr/lib/libc-client.so + fi + + id -g ${run_group} >/dev/null 2>&1 + [ $? -ne 0 ] && groupadd ${run_group} + id -u ${run_user} >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -g ${run_group} -M -s /sbin/nologin ${run_user} + + # PHP enables the sqlite3 extension by default; its configure step fails with + # "Package 'sqlite3' not found" when libsqlite3-dev is missing. Install it on + # demand so a skipped/partial dependency stage cannot break the PHP build. + if ! pkg-config --exists sqlite3 >/dev/null 2>&1; then + echo "${CMSG}Installing libsqlite3-dev (required by PHP sqlite3 extension)...${CEND}" + apt-get -y install libsqlite3-dev + fi + + tar xzf php-${php80_ver}.tar.gz + pushd php-${php80_ver} > /dev/null + if [ -e ext/openssl/openssl.c ] && ! grep -Eqi '^#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c; then + sed -i '/OPENSSL_SSLV23_PADDING/i#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c + sed -i '/OPENSSL_SSLV23_PADDING/a#endif' ext/openssl/openssl.c + fi + make clean + # Include the self-built curl's pkgconfig dir so PHP's pkg-config based + # ext/curl detection (PKG_CHECK_MODULES libcurl) can find libcurl.pc. + export PKG_CONFIG_PATH=${curl_install_dir}/lib/pkgconfig/:/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH + # PHP ext/curl uses pkg-config to locate libcurl; if it still can't be found + # (self-built curl .pc missing), fall back to the system dev package. + if ! pkg-config --exists libcurl >/dev/null 2>&1; then + echo "${CMSG}libcurl.pc not found, installing libcurl4-openssl-dev...${CEND}" + apt-get -y install libcurl4-openssl-dev + fi + [ ! -d "${php_install_dir}" ] && mkdir -p ${php_install_dir} + [ "${phpcache_option}" == '1' ] && phpcache_arg='--enable-opcache' || phpcache_arg='--disable-opcache' + ./configure --prefix=${php_install_dir} --with-config-file-path=${php_install_dir}/etc \ + --with-config-file-scan-dir=${php_install_dir}/etc/php.d \ + --with-fpm-user=${run_user} --with-fpm-group=${run_group} --enable-fpm ${phpcache_arg} --disable-fileinfo \ + --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \ + --with-iconv=/usr/local --with-freetype --with-jpeg --with-zlib \ + --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-exif \ + --enable-sysvsem ${php80_with_curl} --enable-mbregex \ + --enable-mbstring --with-password-argon2 --with-sodium=/usr/local --enable-gd ${php80_with_openssl} \ + --with-mhash --enable-pcntl --enable-sockets --enable-ftp --enable-intl --with-xsl \ + --with-gettext --with-zip=/usr/local --enable-soap --disable-debug ${php_modules_options} + make ZEND_EXTRA_LIBS='-liconv' -j ${THREAD} + make install + + if [ -e "${php_install_dir}/bin/phpize" ]; then + [ ! -e "${php_install_dir}/etc/php.d" ] && mkdir -p ${php_install_dir}/etc/php.d + echo "${CSUCCESS}PHP installed successfully! ${CEND}" + else + rm -rf ${php_install_dir} + echo "${CFAILURE}PHP install failed, Please Contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + + [ -z "`grep ^'export PATH=' /etc/profile`" ] && echo "export PATH=${php_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "`grep ^'export PATH=' /etc/profile`" -a -z "`grep ${php_install_dir} /etc/profile`" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${php_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + # wget -c http://pear.php.net/go-pear.phar + # ${php_install_dir}/bin/php go-pear.phar + + /bin/cp php.ini-production ${php_install_dir}/etc/php.ini + + sed -i "s@^memory_limit.*@memory_limit = ${Memory_limit}M@" ${php_install_dir}/etc/php.ini + sed -i 's@^output_buffering =@output_buffering = On\noutput_buffering =@' ${php_install_dir}/etc/php.ini + #sed -i 's@^;cgi.fix_pathinfo.*@cgi.fix_pathinfo=0@' ${php_install_dir}/etc/php.ini + sed -i 's@^short_open_tag = Off@short_open_tag = On@' ${php_install_dir}/etc/php.ini + sed -i 's@^expose_php = On@expose_php = Off@' ${php_install_dir}/etc/php.ini + sed -i 's@^request_order.*@request_order = "CGP"@' ${php_install_dir}/etc/php.ini + sed -i "s@^;date.timezone.*@date.timezone = ${timezone}@" ${php_install_dir}/etc/php.ini + sed -i 's@^post_max_size.*@post_max_size = 100M@' ${php_install_dir}/etc/php.ini + sed -i 's@^upload_max_filesize.*@upload_max_filesize = 50M@' ${php_install_dir}/etc/php.ini + sed -i 's@^max_execution_time.*@max_execution_time = 600@' ${php_install_dir}/etc/php.ini + sed -i 's@^;realpath_cache_size.*@realpath_cache_size = 2M@' ${php_install_dir}/etc/php.ini + sed -i 's@^disable_functions.*@disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen@' ${php_install_dir}/etc/php.ini + [ -e /usr/sbin/sendmail ] && sed -i 's@^;sendmail_path.*@sendmail_path = /usr/sbin/sendmail -t -i@' ${php_install_dir}/etc/php.ini + if [ "${with_old_openssl_flag}" = 'y' ]; then + sed -i "s@^;curl.cainfo.*@curl.cainfo = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.cafile.*@openssl.cafile = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.capath.*@openssl.capath = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + fi + + [ "${phpcache_option}" == '1' ] && cat > ${php_install_dir}/etc/php.d/02-opcache.ini << EOF +[opcache] +zend_extension=opcache.so +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=${Memory_limit} +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=100000 +opcache.max_wasted_percentage=5 +opcache.use_cwd=1 +opcache.validate_timestamps=1 +opcache.revalidate_freq=60 +;opcache.save_comments=0 +opcache.consistency_checks=0 +;opcache.optimization_level=0 +EOF + + # php-fpm Init Script + /bin/cp ${oneinstack_dir}/services/php-fpm.service /lib/systemd/system/ + sed -i "s@/usr/local/php@${php_install_dir}@g" /lib/systemd/system/php-fpm.service + systemctl enable php-fpm + + cat > ${php_install_dir}/etc/php-fpm.conf < /dev/null + [ -e "${php_install_dir}/bin/phpize" ] && rm -rf php-${php80_ver} + popd > /dev/null +} diff --git a/modules/php/php-8.1.sh b/modules/php/php-8.1.sh new file mode 100644 index 0000000..bb63a37 --- /dev/null +++ b/modules/php/php-8.1.sh @@ -0,0 +1,274 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_PHP81() { + pushd ${oneinstack_dir}/src > /dev/null + if [ ! -e "/usr/local/lib/libiconv.la" ]; then + tar xzf libiconv-${libiconv_ver}.tar.gz + pushd libiconv-${libiconv_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libiconv-${libiconv_ver} + fi + + if [ ! -e "${curl_install_dir}/lib/libcurl.la" ]; then + tar xzf curl-${curl_ver}.tar.gz + pushd curl-${curl_ver} > /dev/null + ./configure --prefix=${curl_install_dir} ${php81_with_ssl} + make -j ${THREAD} && make install + popd > /dev/null + rm -rf curl-${curl_ver} + fi + + if [ ! -e "${freetype_install_dir}/lib/libfreetype.la" ]; then + tar xzf freetype-${freetype_ver}.tar.gz + pushd freetype-${freetype_ver} > /dev/null + ./configure --prefix=${freetype_install_dir} --enable-freetype-config + make -j ${THREAD} && make install + ln -sf ${freetype_install_dir}/include/freetype2/* /usr/include/ + [ -d /usr/lib/pkgconfig ] && /bin/cp ${freetype_install_dir}/lib/pkgconfig/freetype2.pc /usr/lib/pkgconfig/ + popd > /dev/null + rm -rf freetype-${freetype_ver} + fi + + if [ ! -e "/usr/local/lib/pkgconfig/libargon2.pc" ]; then + tar xzf argon2-${argon2_ver}.tar.gz + pushd argon2-${argon2_ver} > /dev/null + make -j ${THREAD} && make install + [ ! -d /usr/local/lib/pkgconfig ] && mkdir -p /usr/local/lib/pkgconfig + /bin/cp libargon2.pc /usr/local/lib/pkgconfig/ + popd > /dev/null + rm -rf argon2-${argon2_ver} + fi + + if [ ! -e "/usr/local/lib/libsodium.la" ]; then + tar xzf libsodium-${libsodium_ver}.tar.gz + pushd libsodium-${libsodium_ver} > /dev/null + ./configure --disable-dependency-tracking --enable-minimal + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libsodium-${libsodium_ver} + fi + + if [ ! -e "/usr/local/lib/libzip.la" ]; then + tar xzf libzip-${libzip_ver}.tar.gz + pushd libzip-${libzip_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf libzip-${libzip_ver} + fi + + if [ ! -e "/usr/local/include/mhash.h" -a ! -e "/usr/include/mhash.h" ]; then + tar xzf mhash-${mhash_ver}.tar.gz + pushd mhash-${mhash_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + rm -rf mhash-${mhash_ver} + fi + + [ -z "`grep /usr/local/lib /etc/ld.so.conf.d/*.conf`" ] && echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf + ldconfig + + if [ "${PM}" == 'yum' ]; then + [ ! -e "/lib64/libpcre.so.1" ] && ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1 + [ ! -e "/usr/lib/libc-client.so" ] && ln -s /usr/lib64/libc-client.so /usr/lib/libc-client.so + fi + + id -g ${run_group} >/dev/null 2>&1 + [ $? -ne 0 ] && groupadd ${run_group} + id -u ${run_user} >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -g ${run_group} -M -s /sbin/nologin ${run_user} + + # PHP enables the sqlite3 extension by default; its configure step fails with + # "Package 'sqlite3' not found" when libsqlite3-dev is missing. Install it on + # demand so a skipped/partial dependency stage cannot break the PHP build. + if ! pkg-config --exists sqlite3 >/dev/null 2>&1; then + echo "${CMSG}Installing libsqlite3-dev (required by PHP sqlite3 extension)...${CEND}" + apt-get -y install libsqlite3-dev + fi + + tar xzf php-${php81_ver}.tar.gz + pushd php-${php81_ver} > /dev/null + make clean + # Include the self-built curl's pkgconfig dir so PHP's pkg-config based + # ext/curl detection (PKG_CHECK_MODULES libcurl) can find libcurl.pc. + export PKG_CONFIG_PATH=${curl_install_dir}/lib/pkgconfig/:/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH + # PHP ext/curl uses pkg-config to locate libcurl; if it still can't be found + # (self-built curl .pc missing), fall back to the system dev package. + if ! pkg-config --exists libcurl >/dev/null 2>&1; then + echo "${CMSG}libcurl.pc not found, installing libcurl4-openssl-dev...${CEND}" + apt-get -y install libcurl4-openssl-dev + fi + [ ! -d "${php_install_dir}" ] && mkdir -p ${php_install_dir} + [ "${phpcache_option}" == '1' ] && phpcache_arg='--enable-opcache' || phpcache_arg='--disable-opcache' + ./configure --prefix=${php_install_dir} --with-config-file-path=${php_install_dir}/etc \ + --with-config-file-scan-dir=${php_install_dir}/etc/php.d \ + --with-fpm-user=${run_user} --with-fpm-group=${run_group} --enable-fpm ${phpcache_arg} --disable-fileinfo \ + --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \ + --with-iconv=/usr/local --with-freetype --with-jpeg --with-zlib \ + --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-exif \ + --enable-sysvsem ${php81_with_curl} --enable-mbregex \ + --enable-mbstring --with-password-argon2 --with-sodium=/usr/local --enable-gd ${php81_with_openssl} \ + --with-mhash --enable-pcntl --enable-sockets --enable-ftp --enable-intl --with-xsl \ + --with-gettext --with-zip=/usr/local --enable-soap --disable-debug ${php_modules_options} + make ZEND_EXTRA_LIBS='-liconv' -j ${THREAD} + make install + + if [ -e "${php_install_dir}/bin/phpize" ]; then + [ ! -e "${php_install_dir}/etc/php.d" ] && mkdir -p ${php_install_dir}/etc/php.d + echo "${CSUCCESS}PHP installed successfully! ${CEND}" + else + rm -rf ${php_install_dir} + echo "${CFAILURE}PHP install failed, Please Contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + + [ -z "`grep ^'export PATH=' /etc/profile`" ] && echo "export PATH=${php_install_dir}/bin:\$PATH" >> /etc/profile + [ -n "`grep ^'export PATH=' /etc/profile`" -a -z "`grep ${php_install_dir} /etc/profile`" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${php_install_dir}/bin:\1@" /etc/profile + . /etc/profile + + # wget -c http://pear.php.net/go-pear.phar + # ${php_install_dir}/bin/php go-pear.phar + + /bin/cp php.ini-production ${php_install_dir}/etc/php.ini + + sed -i "s@^memory_limit.*@memory_limit = ${Memory_limit}M@" ${php_install_dir}/etc/php.ini + sed -i 's@^output_buffering =@output_buffering = On\noutput_buffering =@' ${php_install_dir}/etc/php.ini + #sed -i 's@^;cgi.fix_pathinfo.*@cgi.fix_pathinfo=0@' ${php_install_dir}/etc/php.ini + sed -i 's@^short_open_tag = Off@short_open_tag = On@' ${php_install_dir}/etc/php.ini + sed -i 's@^expose_php = On@expose_php = Off@' ${php_install_dir}/etc/php.ini + sed -i 's@^request_order.*@request_order = "CGP"@' ${php_install_dir}/etc/php.ini + sed -i "s@^;date.timezone.*@date.timezone = ${timezone}@" ${php_install_dir}/etc/php.ini + sed -i 's@^post_max_size.*@post_max_size = 100M@' ${php_install_dir}/etc/php.ini + sed -i 's@^upload_max_filesize.*@upload_max_filesize = 50M@' ${php_install_dir}/etc/php.ini + sed -i 's@^max_execution_time.*@max_execution_time = 600@' ${php_install_dir}/etc/php.ini + sed -i 's@^;realpath_cache_size.*@realpath_cache_size = 2M@' ${php_install_dir}/etc/php.ini + sed -i 's@^disable_functions.*@disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,readlink,symlink,popepassthru,stream_socket_server,fsocket,popen@' ${php_install_dir}/etc/php.ini + [ -e /usr/sbin/sendmail ] && sed -i 's@^;sendmail_path.*@sendmail_path = /usr/sbin/sendmail -t -i@' ${php_install_dir}/etc/php.ini + if [ "${with_old_openssl_flag}" = 'y' ]; then + sed -i "s@^;curl.cainfo.*@curl.cainfo = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.cafile.*@openssl.cafile = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + sed -i "s@^;openssl.capath.*@openssl.capath = \"${openssl_install_dir}/cert.pem\"@" ${php_install_dir}/etc/php.ini + fi + + [ "${phpcache_option}" == '1' ] && cat > ${php_install_dir}/etc/php.d/02-opcache.ini << EOF +[opcache] +zend_extension=opcache.so +opcache.enable=1 +opcache.enable_cli=1 +opcache.memory_consumption=${Memory_limit} +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=100000 +opcache.max_wasted_percentage=5 +opcache.use_cwd=1 +opcache.validate_timestamps=1 +opcache.revalidate_freq=60 +;opcache.save_comments=0 +opcache.consistency_checks=0 +;opcache.optimization_level=0 +EOF + + # php-fpm Init Script + /bin/cp ${oneinstack_dir}/services/php-fpm.service /lib/systemd/system/ + sed -i "s@/usr/local/php@${php_install_dir}@g" /lib/systemd/system/php-fpm.service + systemctl enable php-fpm + + cat > ${php_install_dir}/etc/php-fpm.conf < /dev/null + [ -e "${php_install_dir}/bin/phpize" ] && rm -rf php-${php81_ver} + popd > /dev/null +} diff --git a/modules/security/fail2ban.sh b/modules/security/fail2ban.sh new file mode 100644 index 0000000..ca5356b --- /dev/null +++ b/modules/security/fail2ban.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_fail2ban() { + pushd ${oneinstack_dir}/src > /dev/null + src_url=http://mirrors.linuxeye.com/oneinstack/src/fail2ban-${fail2ban_ver}.tar.gz && Download_src + tar xzf fail2ban-${fail2ban_ver}.tar.gz + pushd fail2ban-${fail2ban_ver} > /dev/null + sed -i 's@for i in xrange(50)@for i in range(50)@' fail2ban/__init__.py + ${python_install_dir}/bin/python setup.py install + if [ -e /bin/systemctl ]; then + /bin/cp build/fail2ban.service /lib/systemd/system/ + systemctl enable fail2ban + else + if [ "${PM}" == 'yum' ]; then + /bin/cp files/redhat-initd /etc/services/fail2ban + sed -i "s@^FAIL2BAN=.*@FAIL2BAN=${python_install_dir}/bin/fail2ban-client@" /etc/services/fail2ban + sed -i 's@Starting fail2ban.*@&\n [ ! -e "/var/run/fail2ban" ] \&\& mkdir /var/run/fail2ban@' /etc/services/fail2ban + chmod +x /etc/services/fail2ban + chkconfig --add fail2ban + chkconfig fail2ban on + elif [ "${PM}" == 'apt-get' ]; then + /bin/cp files/debian-initd /etc/services/fail2ban + sed -i 's@2 3 4 5@3 4 5@' /etc/services/fail2ban + sed -i "s@^DAEMON=.*@DAEMON=${python_install_dir}/bin/\$NAME-client@" /etc/services/fail2ban + chmod +x /etc/services/fail2ban + update-rc.d fail2ban defaults + fi + fi + [ -z "`grep ^Port /etc/ssh/sshd_config`" ] && now_ssh_port=22 || now_ssh_port=`grep ^Port /etc/ssh/sshd_config | awk '{print $2}' | head -1` + [ "${PM}" == 'yum' ] && LOGPATH=/var/log/secure + [ "${PM}" == 'apt-get' ] && LOGPATH=/var/log/auth.log + cat > /etc/fail2ban/jail.local << EOF +[DEFAULT] +ignoreip = 127.0.0.1/8 +bantime = 86400 +findtime = 600 +maxretry = 5 +[ssh-iptables] +enabled = true +filter = sshd +action = iptables[name=SSH, port=${now_ssh_port}, protocol=tcp] +logpath = ${LOGPATH} +EOF + cat > /etc/logrotate.d/fail2ban << EOF +/var/log/fail2ban.log { + missingok + notifempty + postrotate + ${python_install_dir}/bin/fail2ban-client flushlogs >/dev/null || true + endscript +} +EOF + sed -i 's@^iptables = iptables.*@iptables = iptables@' /etc/fail2ban/action.d/iptables-common.conf + kill -9 `ps -ef | grep fail2ban | grep -v grep | awk '{print $2}'` > /dev/null 2>&1 + service fail2ban start + popd > /dev/null + if [ -e "${python_install_dir}/bin/fail2ban-server" ]; then + echo; echo "${CSUCCESS}fail2ban installed successfully! ${CEND}" + else + echo; echo "${CFAILURE}fail2ban install failed, Please try again! ${CEND}" + fi + popd > /dev/null +} + +Uninstall_fail2ban() { + service fail2ban stop + ${python_install_dir}/bin/pip uninstall -y fail2ban > /dev/null 2>&1 + rm -rf /etc/services/fail2ban /etc/fail2ban /etc/logrotate.d/fail2ban /var/log/fail2ban.* /var/run/fail2ban + echo; echo "${CMSG}fail2ban uninstall completed${CEND}"; +} diff --git a/modules/security/ngx_lua_waf.sh b/modules/security/ngx_lua_waf.sh new file mode 100644 index 0000000..f90a5f4 --- /dev/null +++ b/modules/security/ngx_lua_waf.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Nginx_lua_waf() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e "${nginx_install_dir}/sbin/nginx" ] && echo "${CWARNING}Nginx is not installed on your system! ${CEND}" && exit 1 + if [ ! -e "/usr/local/lib/libluajit-5.1.so.2.1.0" ]; then + [ -e "/usr/local/lib/libluajit-5.1.so.2.0.5" ] && find /usr/local -name *luajit* | xargs rm -rf + src_url=http://mirrors.linuxeye.com/oneinstack/src/luajit2-${luajit2_ver}.tar.gz && Download_src + tar xzf luajit2-${luajit2_ver}.tar.gz + pushd luajit2-${luajit2_ver} + make && make install + [ ! -e "/usr/local/lib/libluajit-5.1.so.2.1.0" ] && { echo "${CFAILURE}LuaJIT install failed! ${CEND}"; kill -9 $$; exit 1; } + popd > /dev/null + rm -rf luajit2-${luajit2_ver} + fi + + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-resty-core-${lua_resty_core_ver}.tar.gz && Download_src + tar xzf lua-resty-core-${lua_resty_core_ver}.tar.gz + pushd lua-resty-core-${lua_resty_core_ver} + make install + popd > /dev/null + rm -rf lua-resty-core-${lua_resty_core_ver} + + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-resty-lrucache-${lua_resty_lrucache_ver}.tar.gz && Download_src + tar xzf lua-resty-lrucache-${lua_resty_lrucache_ver}.tar.gz + pushd lua-resty-lrucache-${lua_resty_lrucache_ver} + make install + popd > /dev/null + rm -rf lua-resty-lrucache-${lua_resty_lrucache_ver} + + [ ! -h "/usr/local/share/lua/5.1" ] && { rm -rf /usr/local/share/lua/5.1 ; ln -s /usr/local/lib/lua /usr/local/share/lua/5.1; } + if [ ! -e "/usr/local/lib/lua/5.1/cjson.so" ]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-cjson-${lua_cjson_ver}.tar.gz && Download_src + tar xzf lua-cjson-${lua_cjson_ver}.tar.gz + pushd lua-cjson-${lua_cjson_ver} + sed -i 's@^LUA_INCLUDE_DIR.*@&/luajit-2.1@' Makefile + make && make install + [ ! -e "/usr/local/lib/lua/5.1/cjson.so" ] && { echo "${CFAILURE}lua-cjson install failed! ${CEND}"; kill -9 $$; exit 1; } + popd > /dev/null + fi + ${nginx_install_dir}/sbin/nginx -V &> $$ + nginx_configure_args_tmp=`cat $$ | grep 'configure arguments:' | awk -F: '{print $2}'` + rm -rf $$ + nginx_configure_args=`echo ${nginx_configure_args_tmp} | sed "s@--with-openssl=../openssl-\w.\w.\w\+ @--with-openssl=../openssl-${openssl11_ver} @" | sed "s@--with-pcre=../pcre-\w.\w\+ @--with-pcre=../pcre-${pcre_ver} @"` + if [ -z "`echo ${nginx_configure_args} | grep lua-nginx-module`" ]; then + src_url=http://nginx.org/download/nginx-${nginx_ver}.tar.gz && Download_src + src_url=https://www.openssl.org/source/openssl-${openssl11_ver}.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/pcre-${pcre_ver}.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/ngx_devel_kit.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-nginx-module-${lua_nginx_module_ver}.tar.gz && Download_src + tar xzf nginx-${nginx_ver}.tar.gz + tar xzf openssl-${openssl11_ver}.tar.gz + tar xzf pcre-${pcre_ver}.tar.gz + tar xzf ngx_devel_kit.tar.gz + tar xzf lua-nginx-module-${lua_nginx_module_ver}.tar.gz + pushd nginx-${nginx_ver} + make clean + sed -i 's@CFLAGS="$CFLAGS -g"@#CFLAGS="$CFLAGS -g"@' auto/cc/gcc # close debug + export LUAJIT_LIB=/usr/local/lib + export LUAJIT_INC=/usr/local/include/luajit-2.1 + ./configure ${nginx_configure_args} --with-ld-opt="-Wl,-rpath,/usr/local/lib" --add-module=../lua-nginx-module-${lua_nginx_module_ver} --add-module=../ngx_devel_kit + make -j ${THREAD} + if [ -f "objs/nginx" ]; then + /bin/mv ${nginx_install_dir}/sbin/nginx{,`date +%m%d`} + /bin/cp objs/nginx ${nginx_install_dir}/sbin/nginx + kill -USR2 `cat /var/run/nginx.pid` + sleep 1 + kill -QUIT `cat /var/run/nginx.pid.oldbin` + popd > /dev/null + echo "${CSUCCESS}lua-nginx-module installed successfully! ${CEND}" + sed -i "s@^nginx_modules_options='\(.*\)'@nginx_modules_options=\'\1 --with-ld-opt=\"-Wl,-rpath,/usr/local/lib\" --add-module=../lua-nginx-module-${lua_nginx_module_ver} --add-module=../ngx_devel_kit\'@" ../config/options.conf + rm -rf nginx-${nginx_ver} + else + echo "${CFAILURE}lua-nginx-module install failed! ${CEND}" + kill -9 $$; exit 1; + fi + fi + popd > /dev/null +} + + +enable_lua_waf() { + pushd ${oneinstack_dir}/src > /dev/null + . ../lib/check_dir.sh + rm -f ngx_lua_waf.tar.gz + src_url=http://mirrors.linuxeye.com/oneinstack/src/ngx_lua_waf.tar.gz && Download_src + tar xzf ngx_lua_waf.tar.gz -C ${web_install_dir}/conf + [ -e "${web_install_dir}/conf/resty" ] && /bin/mv ${web_install_dir}/conf/resty{,_bak} + sed -i "s@/usr/local/nginx@${web_install_dir}@g" ${web_install_dir}/conf/waf.conf + sed -i "s@/usr/local/nginx@${web_install_dir}@" ${web_install_dir}/conf/waf/config.lua + sed -i "s@/data/wwwlogs@${wwwlogs_dir}@" ${web_install_dir}/conf/waf/config.lua + [ -z "`grep 'include waf.conf;' ${web_install_dir}/conf/nginx.conf`" ] && sed -i "s@ vhost/\*.conf;@&\n include waf.conf;@" ${web_install_dir}/conf/nginx.conf + ${web_install_dir}/sbin/nginx -t + if [ $? -eq 0 ]; then + service nginx reload + echo "${CSUCCESS}ngx_lua_waf enabled successfully! ${CEND}" + chown ${run_user}:${run_group} ${wwwlogs_dir} + else + echo "${CFAILURE}ngx_lua_waf enable failed! ${CEND}" + fi + popd > /dev/null +} + +disable_lua_waf() { + pushd ${oneinstack_dir}/src > /dev/null + . ../lib/check_dir.sh + sed -i '/include waf.conf;/d' ${web_install_dir}/conf/nginx.conf + ${web_install_dir}/sbin/nginx -t + if [ $? -eq 0 ]; then + rm -rf ${web_install_dir}/conf/{waf,waf.conf} + service nginx reload + echo "${CSUCCESS}ngx_lua_waf disabled successfully! ${CEND}" + else + echo "${CFAILURE}ngx_lua_waf disable failed! ${CEND}" + fi + popd > /dev/null +} diff --git a/modules/upgrade/upgrade_db.sh b/modules/upgrade/upgrade_db.sh new file mode 100644 index 0000000..1cb08cf --- /dev/null +++ b/modules/upgrade/upgrade_db.sh @@ -0,0 +1,138 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_DB() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e "${db_install_dir}/bin/mysql" ] && echo "${CWARNING}MySQL/MariaDB is not installed on your system! ${CEND}" && exit 1 + [ "${armplatform}" == 'y' ] && echo "${CWARNING}The arm architecture operating system does not support upgrading MySQL/MariaDB! ${CEND}" && exit 1 + + # check db passwd + while :; do + ${db_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "quit" > /dev/null 2>&1 + if [ $? -eq 0 ]; then + break + else + echo + read -e -p "Please input the root password of database: " NEW_dbrootpwd + ${db_install_dir}/bin/mysql -uroot -p${NEW_dbrootpwd} -e "quit" >/dev/null 2>&1 + if [ $? -eq 0 ]; then + dbrootpwd=${NEW_dbrootpwd} + sed -i "s+^dbrootpwd.*+dbrootpwd='$dbrootpwd'+" ../config/options.conf + break + else + echo "${CFAILURE}${DB} root password incorrect,Please enter again! ${CEND}" + fi + fi + done + + OLD_db_ver_tmp=`${db_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e 'select version()\G;' | grep version | awk '{print $2}'` + if [ -n "`${db_install_dir}/bin/mysql -V | grep -o MariaDB`" ]; then + [ "${IPADDR_COUNTRY}"x == "CN"x ] && DOWN_ADDR=https://mirrors.tuna.tsinghua.edu.cn/mariadb || DOWN_ADDR=https://downloads.mariadb.org/f + DB=MariaDB + OLD_db_ver=`echo ${OLD_db_ver_tmp} | awk -F'-' '{print $1}'` + else + [ "${IPADDR_COUNTRY}"x == "CN"x ] && DOWN_ADDR=http://mirrors.ustc.edu.cn/mysql-ftp/Downloads || DOWN_ADDR=http://cdn.mysql.com/Downloads + DB=MySQL + OLD_db_ver=${OLD_db_ver_tmp%%-log} + fi + + #backup + echo + echo "${CSUCCESS}Starting ${DB} backup${CEND}......" + ${db_install_dir}/bin/mysqldump -uroot -p${dbrootpwd} --opt --all-databases > DB_all_backup_$(date +"%Y%m%d").sql + [ -f "DB_all_backup_$(date +"%Y%m%d").sql" ] && echo "${DB} backup success, Backup file: ${MSG}`pwd`/DB_all_backup_$(date +"%Y%m%d").sql${CEND}" + + #upgrade + echo + echo "Current ${DB} Version: ${CMSG}${OLD_db_ver}${CEND}" + while :; do echo + [ "${db_flag}" != 'y' ] && read -e -p "Please input upgrade ${DB} Version(example: ${OLD_db_ver}): " NEW_db_ver + if [ `echo ${NEW_db_ver} | awk -F. '{print $1"."$2}'` == `echo ${OLD_db_ver} | awk -F. '{print $1"."$2}'` ]; then + if [ "${DB}" == 'MariaDB' ]; then + DB_filename=mariadb-${NEW_db_ver}-linux-systemd-x86_64 + DB_URL=${DOWN_ADDR}/mariadb-${NEW_db_ver}/bintar-linux-systemd-x86_64/${DB_filename}.tar.gz + elif [ "${DB}" == 'MySQL' ]; then + DB_filename=mysql-${NEW_db_ver}-linux-glibc2.12-x86_64 + if [ `echo ${OLD_db_ver} | awk -F. '{print $1"."$2}'` == '8.0' ]; then + DB_URL=${DOWN_ADDR}/MySQL-`echo ${NEW_db_ver} | awk -F. '{print $1"."$2}'`/${DB_filename}.tar.xz + else + DB_URL=${DOWN_ADDR}/MySQL-`echo ${NEW_db_ver} | awk -F. '{print $1"."$2}'`/${DB_filename}.tar.gz + fi + fi + [ ! -e "`ls ${DB_filename}.tar.?z 2>/dev/null`" ] && wget --no-check-certificate -c ${DB_URL} > /dev/null 2>&1 + if [ -e "`ls ${DB_filename}.tar.?z 2>/dev/null`" ]; then + echo "Download [${CMSG}`ls ${DB_filename}.tar.?z 2>/dev/null`${CEND}] successfully! " + else + echo "${CWARNING}${DB} version does not exist! ${CEND}" + fi + break + else + echo "${CWARNING}input error! ${CEND}Please only input '${CMSG}${OLD_db_ver%.*}.xx${CEND}'" + [ "${db_flag}" == 'y' ] && exit + fi + done + + if [ -e "`ls ${DB_filename}.tar.?z 2>/dev/null`" ]; then + echo "[${CMSG}`ls ${DB_filename}.tar.?z 2>/dev/null`${CEND}] found" + if [ "${db_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=`get_char` + fi + if [ "${DB}" == 'MariaDB' ]; then + tar xzf ${DB_filename}.tar.gz + service mysqld stop + mv ${mariadb_install_dir}{,_old_`date +"%Y%m%d_%H%M%S"`} + mv ${mariadb_data_dir}{,_old_`date +"%Y%m%d_%H%M%S"`} + [ ! -d "${mariadb_install_dir}" ] && mkdir -p ${mariadb_install_dir} + mkdir -p ${mariadb_data_dir};chown mysql.mysql -R ${mariadb_data_dir} + mv ${DB_filename}/* ${mariadb_install_dir}/ + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mariadb_install_dir}/bin/mysqld_safe + ${mariadb_install_dir}/scripts/mysql_install_db --user=mysql --basedir=${mariadb_install_dir} --datadir=${mariadb_data_dir} + chown mysql.mysql -R ${mariadb_data_dir} + service mysqld start + ${mariadb_install_dir}/bin/mysql < DB_all_backup_$(date +"%Y%m%d").sql + service mysqld restart + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "drop database test;" >/dev/null 2>&1 + ${mariadb_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" >/dev/null 2>&1 + ${mariadb_install_dir}/bin/mysql_upgrade -uroot -p${dbrootpwd} >/dev/null 2>&1 + [ $? -eq 0 ] && echo "You have ${CMSG}successfully${CEND} upgrade from ${CMSG}${OLD_db_ver}${CEND} to ${CMSG}${NEW_db_ver}${CEND}" + elif [ "${DB}" == 'MySQL' ]; then + if [ `echo ${OLD_db_ver} | awk -F. '{print $1"."$2}'` == '8.0' ]; then + tar xJf ${DB_filename}.tar.xz + else + tar xzf ${DB_filename}.tar.gz + fi + service mysqld stop + mv ${mysql_install_dir}{,_old_`date +"%Y%m%d_%H%M%S"`} + mv ${mysql_data_dir}{,_old_`date +"%Y%m%d_%H%M%S"`} + [ ! -d "${mysql_install_dir}" ] && mkdir -p ${mysql_install_dir} + mkdir -p ${mysql_data_dir};chown mysql.mysql -R ${mysql_data_dir} + mv ${DB_filename}/* ${mysql_install_dir}/ + sed -i 's@executing mysqld_safe@executing mysqld_safe\nexport LD_PRELOAD=/usr/local/lib/libjemalloc.so@' ${mysql_install_dir}/bin/mysqld_safe + sed -i "s@/usr/local/mysql@${mysql_install_dir}@g" ${mysql_install_dir}/bin/mysqld_safe + if [[ "`echo ${NEW_db_ver} | awk -F. '{print $1"."$2}'`" =~ ^5.[5-6]$ ]]; then + ${mysql_install_dir}/scripts/mysql_install_db --user=mysql --basedir=${mysql_install_dir} --datadir=${mysql_data_dir} + else + ${mysql_install_dir}/bin/mysqld --initialize-insecure --user=mysql --basedir=${mysql_install_dir} --datadir=${mysql_data_dir} + fi + + chown mysql.mysql -R ${mysql_data_dir} + [ -e "${mysql_install_dir}/my.cnf" ] && rm -rf ${mysql_install_dir}/my.cnf + sed -i '/myisam_repair_threads/d' /etc/my.cnf + service mysqld start + ${mysql_install_dir}/bin/mysql < DB_all_backup_$(date +"%Y%m%d").sql + service mysqld restart + ${mysql_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "drop database test;" >/dev/null 2>&1 + ${mysql_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "reset master;" >/dev/null 2>&1 + ${mysql_install_dir}/bin/mysql_upgrade -uroot -p${dbrootpwd} >/dev/null 2>&1 + [ $? -eq 0 ] && echo "You have ${CMSG}successfully${CEND} upgrade from ${CMSG}${OLD_db_ver}${CEND} to ${CMSG}${NEW_db_ver}${CEND}" + fi + fi +} diff --git a/modules/upgrade/upgrade_oneinstack.sh b/modules/upgrade/upgrade_oneinstack.sh new file mode 100644 index 0000000..ba7c55c --- /dev/null +++ b/modules/upgrade/upgrade_oneinstack.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_OneinStack() { + pushd ${oneinstack_dir} > /dev/null + Latest_OneinStack_MD5=$(curl --connect-timeout 3 -m 5 -s http://mirrors.linuxeye.com/md5sum.txt | grep oneinstack.tar.gz | awk '{print $1}') + [ ! -e README.md ] && ois_flag=n + if [ "${oneinstack_md5}" != "${Latest_OneinStack_MD5}" ]; then + /bin/mv config/options.conf /tmp + sed -i '/oneinstack_dir=/d' /tmp/config/options.conf + [ -e /tmp/oneinstack.tar.gz ] && rm -rf /tmp/oneinstack.tar.gz + wget -qc http://mirrors.linuxeye.com/oneinstack.tar.gz -O /tmp/oneinstack.tar.gz + if [ -n "`echo ${oneinstack_dir} | grep lnmp`" ]; then + tar xzf /tmp/oneinstack.tar.gz -C /tmp + /bin/cp -R /tmp/oneinstack/* ${oneinstack_dir}/ + /bin/rm -rf /tmp/oneinstack + else + tar xzf /tmp/oneinstack.tar.gz -C ../ + fi + IFS=$'\n' + for L in `grep -vE '^#|^$' /tmp/config/options.conf` + do + IFS=$IFS_old + Key="`echo ${L%%=*}`" + Value="`echo ${L#*=}`" + sed -i "s|^${Key}=.*|${Key}=${Value}|" ./config/options.conf + done + rm -rf /tmp/{oneinstack.tar.gz,config/options.conf} + [ "${ois_flag}" == "n" ] && rm -f ss.sh LICENSE README.md + sed -i "s@^oneinstack_md5=.*@oneinstack_md5=${Latest_OneinStack_MD5}@" ./config/options.conf + if [ -e "${php_install_dir}/sbin/php-fpm" ]; then + [ -n "`grep ^cgi.fix_pathinfo=0 ${php_install_dir}/etc/php.ini`" ] && sed -i 's@^cgi.fix_pathinfo.*@;&@' ${php_install_dir}/etc/php.ini + [ -e "/usr/local/php53/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php53/etc/php.ini 2>/dev/null + [ -e "/usr/local/php54/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php54/etc/php.ini 2>/dev/null + [ -e "/usr/local/php55/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php55/etc/php.ini 2>/dev/null + [ -e "/usr/local/php56/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php56/etc/php.ini 2>/dev/null + [ -e "/usr/local/php70/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php70/etc/php.ini 2>/dev/null + [ -e "/usr/local/php71/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php71/etc/php.ini 2>/dev/null + [ -e "/usr/local/php72/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php72/etc/php.ini 2>/dev/null + [ -e "/usr/local/php73/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php73/etc/php.ini 2>/dev/null + [ -e "/usr/local/php74/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php74/etc/php.ini 2>/dev/null + [ -e "/usr/local/php80/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php80/etc/php.ini 2>/dev/null + [ -e "/usr/local/php81/etc/php.ini" ] && sed -i 's@^cgi.fix_pathinfo=0@;&@' /usr/local/php81/etc/php.ini 2>/dev/null + fi + [ -e "/lib/systemd/system/php-fpm.service" ] && { sed -i 's@^PrivateTmp.*@#&@g' /lib/systemd/system/php-fpm.service; systemctl daemon-reload; } + echo + echo "${CSUCCESS}Congratulations! OneinStack upgrade successful! ${CEND}" + echo + else + echo "${CWARNING}Your OneinStack already has the latest version or does not need to be upgraded! ${CEND}" + fi + popd > /dev/null +} diff --git a/modules/upgrade/upgrade_php.sh b/modules/upgrade/upgrade_php.sh new file mode 100644 index 0000000..de42083 --- /dev/null +++ b/modules/upgrade/upgrade_php.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_PHP() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e "${php_install_dir}" ] && echo "${CWARNING}PHP is not installed on your system! ${CEND}" && exit 1 + OLD_php_ver=`${php_install_dir}/bin/php-config --version` + Latest_php_ver=`curl --connect-timeout 2 -m 3 -s https://www.php.net/releases/active.php | python -mjson.tool | awk '/version/{print $2}' | sed 's/"//g' | grep "${OLD_php_ver%.*}"` + Latest_php_ver=${Latest_php_ver:-8.1.12} + echo + echo "Current PHP Version: ${CMSG}$OLD_php_ver${CEND}" + while :; do echo + [ "${php_flag}" != 'y' ] && read -e -p "Please input upgrade PHP Version(Default: $Latest_php_ver): " NEW_php_ver + NEW_php_ver=${NEW_php_ver:-${Latest_php_ver}} + if [ "${NEW_php_ver%.*}" == "${OLD_php_ver%.*}" ]; then + [ ! -e "php-${NEW_php_ver}.tar.gz" ] && wget --no-check-certificate -c https://secure.php.net/distributions/php-${NEW_php_ver}.tar.gz > /dev/null 2>&1 + if [ -e "php-${NEW_php_ver}.tar.gz" ]; then + echo "Download [${CMSG}php-${NEW_php_ver}.tar.gz${CEND}] successfully! " + else + echo "${CWARNING}PHP version does not exist! ${CEND}" + fi + break + else + echo "${CWARNING}input error! ${CEND}Please only input '${CMSG}${OLD_php_ver%.*}.xx${CEND}'" + [ "${php_flag}" == 'y' ] && exit + fi + done + + if [ -e "php-${NEW_php_ver}.tar.gz" ]; then + echo "[${CMSG}php-${NEW_php_ver}.tar.gz${CEND}] found" + if [ "${php_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=`get_char` + fi + tar xzf php-${NEW_php_ver}.tar.gz + if [[ "${OLD_php_ver%.*}" =~ ^5.[3-6]$ ]]; then + src_url=http://mirrors.linuxeye.com/oneinstack/src/fpm-race-condition.patch && Download_src + patch -d php-${NEW_php_ver} -p0 < fpm-race-condition.patch + fi + pushd php-${NEW_php_ver} + if [[ "${OLD_php_ver%.*}" =~ ^7.[1-4]$|^8.[0-1]$ ]] && [ -e ext/openssl/openssl.c ] && ! grep -Eqi '^#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c; then + sed -i '/OPENSSL_SSLV23_PADDING/i#ifdef RSA_SSLV23_PADDING' ext/openssl/openssl.c + sed -i '/OPENSSL_SSLV23_PADDING/a#endif' ext/openssl/openssl.c + fi + make clean + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH + ${php_install_dir}/bin/php -i |grep 'Configure Command' | awk -F'=>' '{print $2}' | bash + make ZEND_EXTRA_LIBS='-liconv' -j ${THREAD} + echo "Stoping php-fpm..." + service php-fpm stop + make install + echo "Starting php-fpm..." + service php-fpm start + popd > /dev/null + echo "You have ${CMSG}successfully${CEND} upgrade from ${CWARNING}$OLD_php_ver${CEND} to ${CWARNING}${NEW_php_ver}${CEND}" + rm -rf php-${NEW_php_ver} + fi + popd > /dev/null +} diff --git a/modules/upgrade/upgrade_phpmyadmin.sh b/modules/upgrade/upgrade_phpmyadmin.sh new file mode 100644 index 0000000..7461dbe --- /dev/null +++ b/modules/upgrade/upgrade_phpmyadmin.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_phpMyAdmin() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e "${wwwroot_dir}/default/phpMyAdmin" ] && echo "${CWARNING}phpMyAdmin is not installed on your system! ${CEND}" && exit 1 + OLD_phpmyadmin_ver=`grep Version ${wwwroot_dir}/default/phpMyAdmin/README | awk '{print $2}'` + Latest_phpmyadmin_ver=`curl --connect-timeout 2 -m 3 -s https://www.phpmyadmin.net/files/ | awk -F'>|<' '/\/files\/[0-9]/{print $5}' | head -1` + Latest_phpmyadmin_ver=${Latest_phpmyadmin_ver:-5.0.4} + echo "Current phpMyAdmin Version: ${CMSG}${OLD_phpmyadmin_ver}${CEND}" + while :; do echo + [ "${phpmyadmin_flag}" != 'y' ] && read -e -p "Please input upgrade phpMyAdmin Version(default: ${Latest_phpmyadmin_ver}): " NEW_phpmyadmin_ver + NEW_phpmyadmin_ver=${NEW_phpmyadmin_ver:-${Latest_phpmyadmin_ver}} + if [ "${NEW_phpmyadmin_ver}" != "${OLD_phpmyadmin_ver}" ]; then + [ ! -e "phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz" ] && wget --no-check-certificate -c https://files.phpmyadmin.net/phpMyAdmin/${NEW_phpmyadmin_ver}/phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz > /dev/null 2>&1 + if [ -e "phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz" ]; then + echo "Download [${CMSG}phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz${CEND}] successfully! " + break + else + echo "${CWARNING}phpMyAdmin version does not exist! ${CEND}" + fi + else + echo "${CWARNING}input error! Upgrade phpMyAdmin version is the same as the old version${CEND}" + exit + fi + done + + if [ -e "phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz" ]; then + echo "[${CMSG}phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz${CEND}] found" + if [ "${phpmyadmin_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=`get_char` + fi + tar xzf phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages.tar.gz + rm -rf ${wwwroot_dir}/default/phpMyAdmin + /bin/mv phpMyAdmin-${NEW_phpmyadmin_ver}-all-languages ${wwwroot_dir}/default/phpMyAdmin + /bin/cp ${wwwroot_dir}/default/phpMyAdmin/{config.sample.inc.php,config.inc.php} + mkdir ${wwwroot_dir}/default/phpMyAdmin/{upload,save} + sed -i "s@UploadDir.*@UploadDir'\] = 'upload';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@SaveDir.*@SaveDir'\] = 'save';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@host'\].*@host'\] = '127.0.0.1';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + sed -i "s@blowfish_secret.*;@blowfish_secret\'\] = \'$(cat /dev/urandom | head -1 | base64 | head -c 45)\';@" ${wwwroot_dir}/default/phpMyAdmin/config.inc.php + chown -R ${run_user}:${run_group} ${wwwroot_dir}/default/phpMyAdmin + echo "You have ${CMSG}successfully${CEND} upgrade from ${CWARNING}$OLD_phpmyadmin_ver${CEND} to ${CWARNING}$NEW_phpmyadmin_ver${CEND}" + fi + popd > /dev/null +} diff --git a/modules/upgrade/upgrade_redis.sh b/modules/upgrade/upgrade_redis.sh new file mode 100644 index 0000000..333afa0 --- /dev/null +++ b/modules/upgrade/upgrade_redis.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_Redis() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -d "$redis_install_dir" ] && echo "${CWARNING}Redis is not installed on your system! ${CEND}" && exit 1 + OLD_redis_ver=`$redis_install_dir/bin/redis-cli --version | awk '{print $2}'` + Latest_redis_ver=`curl --connect-timeout 2 -m 3 -s http://download.redis.io/redis-stable/00-RELEASENOTES | awk '/Released/{print $2}' | head -1` + Latest_redis_ver=${Latest_redis_ver:-6.0.4} + echo "Current Redis Version: ${CMSG}$OLD_redis_ver${CEND}" + while :; do echo + [ "${redis_flag}" != 'y' ] && read -e -p "Please input upgrade Redis Version(default: ${Latest_redis_ver}): " NEW_redis_ver + NEW_redis_ver=${NEW_redis_ver:-${Latest_redis_ver}} + if [ "$NEW_redis_ver" != "$OLD_redis_ver" ]; then + [ ! -e "redis-$NEW_redis_ver.tar.gz" ] && wget --no-check-certificate -c http://download.redis.io/releases/redis-$NEW_redis_ver.tar.gz > /dev/null 2>&1 + if [ -e "redis-$NEW_redis_ver.tar.gz" ]; then + echo "Download [${CMSG}redis-$NEW_redis_ver.tar.gz${CEND}] successfully! " + break + else + echo "${CWARNING}Redis version does not exist! ${CEND}" + fi + else + echo "${CWARNING}input error! Upgrade Redis version is the same as the old version${CEND}" + exit + fi + done + + if [ -e "redis-$NEW_redis_ver.tar.gz" ]; then + echo "[${CMSG}redis-$NEW_redis_ver.tar.gz${CEND}] found" + if [ "${redis_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=`get_char` + fi + tar xzf redis-$NEW_redis_ver.tar.gz + pushd redis-$NEW_redis_ver + make clean + make -j ${THREAD} + + if [ -f "src/redis-server" ]; then + echo "Restarting Redis..." + service redis-server stop + /bin/cp src/{redis-benchmark,redis-check-aof,redis-check-rdb,redis-cli,redis-sentinel,redis-server} $redis_install_dir/bin/ + service redis-server start + popd > /dev/null + echo "You have ${CMSG}successfully${CEND} upgrade from ${CWARNING}$OLD_redis_ver${CEND} to ${CWARNING}$NEW_redis_ver${CEND}" + rm -rf redis-$NEW_redis_ver + else + echo "${CFAILURE}Upgrade Redis failed! ${CEND}" + fi + fi + popd > /dev/null +} diff --git a/modules/upgrade/upgrade_web.sh b/modules/upgrade/upgrade_web.sh new file mode 100644 index 0000000..5f824c1 --- /dev/null +++ b/modules/upgrade/upgrade_web.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Upgrade_Nginx() { + pushd ${oneinstack_dir}/src > /dev/null + [ ! -e "${nginx_install_dir}/sbin/nginx" ] && echo "${CWARNING}Nginx is not installed on your system! ${CEND}" && exit 1 + OLD_nginx_ver_tmp=`${nginx_install_dir}/sbin/nginx -v 2>&1` + OLD_nginx_ver=${OLD_nginx_ver_tmp##*/} + Latest_nginx_ver=`curl --connect-timeout 2 -m 3 -s http://nginx.org/en/CHANGES-1.22 | awk '/Changes with nginx/{print$0}' | awk '{print $4}' | head -1` + [ -z "${Latest_nginx_ver}" ] && Latest_nginx_ver=`curl --connect-timeout 2 -m 3 -s http://nginx.org/en/CHANGES | awk '/Changes with nginx/{print$0}' | awk '{print $4}' | head -1` + echo + echo "Current Nginx Version: ${CMSG}${OLD_nginx_ver}${CEND}" + while :; do echo + [ "${nginx_flag}" != 'y' ] && read -e -p "Please input upgrade Nginx Version(default: ${Latest_nginx_ver}): " NEW_nginx_ver + NEW_nginx_ver=${NEW_nginx_ver:-${Latest_nginx_ver}} + if [ "${NEW_nginx_ver}" != "${OLD_nginx_ver}" ]; then + [ ! -e "nginx-${NEW_nginx_ver}.tar.gz" ] && wget --no-check-certificate -c http://nginx.org/download/nginx-${NEW_nginx_ver}.tar.gz > /dev/null 2>&1 + if [ -e "nginx-${NEW_nginx_ver}.tar.gz" ]; then + src_url=https://www.openssl.org/source/openssl-${openssl11_ver}.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/pcre-${pcre_ver}.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/ngx_devel_kit.tar.gz && Download_src + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-nginx-module-${lua_nginx_module_ver}.tar.gz && Download_src + tar xzf openssl-${openssl11_ver}.tar.gz + tar xzf pcre-${pcre_ver}.tar.gz + tar xzf ngx_devel_kit.tar.gz + tar xzf lua-nginx-module-${lua_nginx_module_ver}.tar.gz + echo "Download [${CMSG}nginx-${NEW_nginx_ver}.tar.gz${CEND}] successfully! " + break + else + echo "${CWARNING}Nginx version does not exist! ${CEND}" + fi + else + echo "${CWARNING}input error! Upgrade Nginx version is the same as the old version${CEND}" + exit + fi + done + + if [ -e "nginx-${NEW_nginx_ver}.tar.gz" ]; then + echo "[${CMSG}nginx-${NEW_nginx_ver}.tar.gz${CEND}] found" + if [ "${nginx_flag}" != 'y' ]; then + echo "Press Ctrl+c to cancel or Press any key to continue..." + char=`get_char` + fi + ${nginx_install_dir}/sbin/nginx -V &> $$ + nginx_configure_args_tmp=`cat $$ | grep 'configure arguments:' | awk -F: '{print $2}'` + rm -rf $$ + nginx_configure_args=`echo ${nginx_configure_args_tmp} | sed "s@lua-nginx-module-\w.\w\+.\w\+ @lua-nginx-module-${lua_nginx_module_ver} @" | sed "s@lua-nginx-module @lua-nginx-module-${lua_nginx_module_ver} @" | sed "s@--with-openssl=../openssl-\w.\w.\w\+ @--with-openssl=../openssl-${openssl11_ver} @" | sed "s@--with-pcre=../pcre-\w.\w\+ @--with-pcre=../pcre-${pcre_ver} @"` + if [ -n `echo $nginx_configure_args | grep lua-nginx-module` ]; then + ${oneinstack_dir}/upgrade.sh --oneinstack > /dev/null + src_url=http://mirrors.linuxeye.com/oneinstack/src/luajit2-${luajit2_ver}.tar.gz && Download_src + tar xzf luajit2-${luajit2_ver}.tar.gz + pushd luajit2-${luajit2_ver} + make && make install + popd > /dev/null + rm -rf luajit2-${luajit2_ver} + + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-resty-core-${lua_resty_core_ver}.tar.gz && Download_src + tar xzf lua-resty-core-${lua_resty_core_ver}.tar.gz + pushd lua-resty-core-${lua_resty_core_ver} + make install + popd > /dev/null + rm -rf lua-resty-core-${lua_resty_core_ver} + + src_url=http://mirrors.linuxeye.com/oneinstack/src/lua-resty-lrucache-${lua_resty_lrucache_ver}.tar.gz && Download_src + tar xzf lua-resty-lrucache-${lua_resty_lrucache_ver}.tar.gz + pushd lua-resty-lrucache-${lua_resty_lrucache_ver} + make install + popd > /dev/null + rm -rf lua-resty-lrucache-${lua_resty_lrucache_ver} + fi + + tar xzf nginx-${NEW_nginx_ver}.tar.gz + pushd nginx-${NEW_nginx_ver} + make clean + sed -i 's@CFLAGS="$CFLAGS -g"@#CFLAGS="$CFLAGS -g"@' auto/cc/gcc # close debug + export LUAJIT_LIB=/usr/local/lib + export LUAJIT_INC=/usr/local/include/luajit-2.1 + ./configure ${nginx_configure_args} + make -j ${THREAD} + if [ -f "objs/nginx" ]; then + /bin/mv ${nginx_install_dir}/sbin/nginx{,`date +%m%d`} + /bin/cp objs/nginx ${nginx_install_dir}/sbin/nginx + kill -USR2 `cat /var/run/nginx.pid` + sleep 1 + kill -QUIT `cat /var/run/nginx.pid.oldbin` + popd > /dev/null + echo "You have ${CMSG}successfully${CEND} upgrade from ${CWARNING}${OLD_nginx_ver}${CEND} to ${CWARNING}${NEW_nginx_ver}${CEND}" + rm -rf nginx-${NEW_nginx_ver} + else + echo "${CFAILURE}Upgrade Nginx failed! ${CEND}" + fi + fi + popd > /dev/null +} + \ No newline at end of file diff --git a/modules/web/jemalloc.sh b/modules/web/jemalloc.sh new file mode 100644 index 0000000..50f4619 --- /dev/null +++ b/modules/web/jemalloc.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_Jemalloc() { + if [ ! -e "/usr/local/lib/libjemalloc.so" ]; then + echo "${CMSG}>> Installing: jemalloc ${jemalloc_ver} (compiling from source)${CEND}" + pushd ${oneinstack_dir}/src > /dev/null + tar xjf jemalloc-${jemalloc_ver}.tar.bz2 + pushd jemalloc-${jemalloc_ver} > /dev/null + ./configure + make -j ${THREAD} && make install + popd > /dev/null + if [ -f "/usr/local/lib/libjemalloc.so" ]; then + if [ "${Family}" == 'rhel' ]; then + ln -s /usr/local/lib/libjemalloc.so.2 /usr/lib64/libjemalloc.so.1 + else + ln -s /usr/local/lib/libjemalloc.so.2 /usr/lib/libjemalloc.so.1 + fi + [ -z "`grep /usr/local/lib /etc/ld.so.conf.d/*.conf`" ] && echo '/usr/local/lib' > /etc/ld.so.conf.d/local.conf + ldconfig + echo "${CSUCCESS}jemalloc module installed successfully! ${CEND}" + rm -rf jemalloc-${jemalloc_ver} + else + echo "${CFAILURE}jemalloc install failed, Please contact the author! ${CEND}" && lsb_release -a + kill -9 $$; exit 1; + fi + popd > /dev/null + fi +} diff --git a/modules/web/nginx.sh b/modules/web/nginx.sh new file mode 100644 index 0000000..3d57313 --- /dev/null +++ b/modules/web/nginx.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +Install_Nginx() { + pushd ${oneinstack_dir}/src > /dev/null + id -g ${run_group} >/dev/null 2>&1 + [ $? -ne 0 ] && groupadd ${run_group} + id -u ${run_user} >/dev/null 2>&1 + [ $? -ne 0 ] && useradd -g ${run_group} -M -s /sbin/nologin ${run_user} + + tar xzf pcre-${pcre_ver}.tar.gz + tar xzf nginx-${nginx_ver}.tar.gz + tar xzf openssl-${openssl11_ver}.tar.gz + tar xzf nginx-rtmp-module.tar.gz + tar xvf ngx-fancyindex-${fancyindex_ver}.tar.xz + pushd nginx-${nginx_ver} > /dev/null + # Modify Nginx version + #sed -i 's@#define NGINX_VERSION.*$@#define NGINX_VERSION "1.2"@' src/core/nginx.h + #sed -i 's@#define NGINX_VER.*NGINX_VERSION$@#define NGINX_VER "Linuxeye/" NGINX_VERSION@' src/core/nginx.h + #sed -i 's@Server: nginx@Server: linuxeye@' src/http/ngx_http_header_filter_module.c + + # close debug + sed -i 's@CFLAGS="$CFLAGS -g"@#CFLAGS="$CFLAGS -g"@' auto/cc/gcc + + [ ! -d "${nginx_install_dir}" ] && mkdir -p ${nginx_install_dir} + ./configure --prefix=${nginx_install_dir} --user=${run_user} --group=${run_group} --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_ssl_module --with-stream --with-stream_ssl_preread_module --with-stream_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-${openssl11_ver} --with-pcre=../pcre-${pcre_ver} --with-pcre-jit --with-ld-opt='-ljemalloc' --add-module=../nginx-rtmp-module --add-module=../ngx-fancyindex-${fancyindex_ver} ${nginx_modules_options} + make -j ${THREAD} && make install + if [ -e "${nginx_install_dir}/conf/nginx.conf" ]; then + popd > /dev/null + rm -rf pcre-${pcre_ver} openssl-${openssl11_ver} nginx-${nginx_ver} nginx-rtmp-module ngx-fancyindex-${fancyindex_ver} + echo "${CSUCCESS}Nginx installed successfully! ${CEND}" + else + rm -rf ${nginx_install_dir} + echo "${CFAILURE}Nginx install failed, Please Contact the author! ${CEND}" + kill -9 $$; exit 1; + fi + + [ -z "`grep ^'export PATH=' /etc/profile`" ] && echo "export PATH=${nginx_install_dir}/sbin:\$PATH" >> /etc/profile + [ -n "`grep ^'export PATH=' /etc/profile`" -a -z "`grep ${nginx_install_dir} /etc/profile`" ] && sed -i "s@^export PATH=\(.*\)@export PATH=${nginx_install_dir}/sbin:\1@" /etc/profile + . /etc/profile + + /bin/cp ../services/nginx.service /lib/systemd/system/ + sed -i "s@/usr/local/nginx@${nginx_install_dir}@g" /lib/systemd/system/nginx.service + systemctl enable nginx + + mv ${nginx_install_dir}/conf/nginx.conf{,_bk} + /bin/cp ../templates/nginx.conf ${nginx_install_dir}/conf/nginx.conf + [[ "${php_option}" =~ ^[1-3]$ ]] && [ -z "`grep '/php-fpm_status' ${nginx_install_dir}/conf/nginx.conf`" ] && sed -i "s@index index.html index.php;@index index.html index.php; + location ~ /php-fpm_status { + #fastcgi_pass remote_php_ip:9000; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_index index.php; + include fastcgi.conf; + allow 127.0.0.1; + deny all; + }@" ${nginx_install_dir}/conf/nginx.conf + cat > ${nginx_install_dir}/conf/proxy.conf << EOF +proxy_connect_timeout 300s; +proxy_send_timeout 900; +proxy_read_timeout 900; +proxy_buffer_size 32k; +proxy_buffers 4 64k; +proxy_busy_buffers_size 128k; +proxy_redirect off; +proxy_hide_header Vary; +proxy_set_header Accept-Encoding ''; +proxy_set_header Referer \$http_referer; +proxy_set_header Cookie \$http_cookie; +proxy_set_header Host \$host; +proxy_set_header X-Real-IP \$remote_addr; +proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto \$scheme; +EOF + sed -i "s@/data/wwwroot/default@${wwwroot_dir}/default@" ${nginx_install_dir}/conf/nginx.conf + sed -i "s@/data/wwwlogs@${wwwlogs_dir}@g" ${nginx_install_dir}/conf/nginx.conf + sed -i "s@^user www www@user ${run_user} ${run_group}@" ${nginx_install_dir}/conf/nginx.conf + + # logrotate nginx log + cat > /etc/logrotate.d/nginx << EOF +${wwwlogs_dir}/*nginx.log { + daily + rotate 5 + missingok + dateext + compress + notifempty + sharedscripts + postrotate + [ -e /var/run/nginx.pid ] && kill -USR1 \`cat /var/run/nginx.pid\` + endscript +} +EOF + popd > /dev/null + ldconfig + systemctl start nginx +} diff --git a/scripts/ckssh.py b/scripts/ckssh.py new file mode 100644 index 0000000..0d49034 --- /dev/null +++ b/scripts/ckssh.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# Author: yeho +# Blog: http://linuxeye.com + +import socket,sys +sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sk.settimeout(1) +try: + sk.connect((sys.argv[1],int(sys.argv[2]))) + print ('ok') +except Exception: + print ('no') +sk.close() diff --git a/scripts/db_bk.sh b/scripts/db_bk.sh new file mode 100644 index 0000000..1c0874b --- /dev/null +++ b/scripts/db_bk.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +. ../config/options.conf +. ../lib/check_dir.sh + +DBname=$1 +LogFile=${backup_dir}/db.log +DumpFile=${backup_dir}/DB_${DBname}_$(date +%Y%m%d_%H%M%S).sql +NewFile=${backup_dir}/DB_${DBname}_$(date +%Y%m%d_%H%M%S).tgz +OldFile=${backup_dir}/DB_${DBname}_$(date +%Y%m%d --date="${expired_days} days ago")*.tgz + +[ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} + +DB_tmp=`${db_install_dir}/bin/mysql -uroot -p${dbrootpwd} -e "show databases\G" | grep ${DBname}` +[ -z "${DB_tmp}" ] && { echo "[${DBname}] not exist" >> ${LogFile} ; exit 1 ; } + +if [ -n "`ls ${OldFile} 2>/dev/null`" ]; then + rm -f ${OldFile} + echo "[${OldFile}] Delete Old File Success" >> ${LogFile} +else + echo "[${OldFile}] Delete Old Backup File" >> ${LogFile} +fi + +if [ -e "${NewFile}" ]; then + echo "[${NewFile}] The Backup File is exists, Can't Backup" >> ${LogFile} +else + ${db_install_dir}/bin/mysqldump -uroot -p${dbrootpwd} --databases ${DBname} > ${DumpFile} + pushd ${backup_dir} > /dev/null + tar czf ${NewFile} ${DumpFile##*/} >> ${LogFile} 2>&1 + echo "[${NewFile}] Backup success ">> ${LogFile} + rm -f ${DumpFile} + popd > /dev/null +fi diff --git a/scripts/mabs.sh b/scripts/mabs.sh new file mode 100644 index 0000000..81c3fac --- /dev/null +++ b/scripts/mabs.sh @@ -0,0 +1,168 @@ +#!/bin/bash +# Author: yeho +# Blog: http://linuxeye.com + +###################### proc defination ######################## +# ignore rule +ignore_init() { + # ignore password + array_ignore_pwd_length=0 + if [ -f ./ignore_pwd ]; then + while read IGNORE_PWD + do + array_ignore_pwd[$array_ignore_pwd_length]=$IGNORE_PWD + let array_ignore_pwd_length=$array_ignore_pwd_length+1 + done < ./ignore_pwd + fi + + # ignore ip address + array_ignore_ip_length=0 + if [ -f ./ignore_ip ]; then + while read IGNORE_IP + do + array_ignore_ip[$array_ignore_ip_length]=$IGNORE_IP + let array_ignore_ip_length=$array_ignore_ip_length+1 + done < ./ignore_ip + fi +} + +show_ver() { + echo "version: 1.0" + echo "updated date: 2014-06-08" +} + +show_usage() { + echo -e "`printf %-16s "Usage: $0"` [-h|--help]" + echo -e "`printf %-16s ` [-v|-V|--version]" + echo -e "`printf %-16s ` [-l|--iplist ... ]" + echo -e "`printf %-16s ` [-c|--config ... ]" + echo -e "`printf %-16s ` [-t|--sshtimeout ... ]" + echo -e "`printf %-16s ` [-T|--fttimeout ... ]" + echo -e "`printf %-16s ` [-L|--bwlimit ... ]" + echo -e "`printf %-16s ` [-n|--ignore]" +} + +IPLIST="iplist.txt" +CONFIG_FILE="config.txt" +IGNRFLAG="noignr" +SSHTIMEOUT=100 +SCPTIMEOUT=2000 +BWLIMIT=1024000 +[ ! -e 'logs' ] && mkdir logs + +TEMP=`getopt -o hvVl:c:t:T:L:n --long help,version,iplist:,config:,sshtimeout:,fttimeout:,bwlimit:,log:,ignore -- "$@" 2>/dev/null` + +[ $? != 0 ] && echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1 + +eval set -- "$TEMP" + +while :; do + [ -z "$1" ] && break; + case "$1" in + -h|--help) + show_usage; exit 0 + ;; + -v|-V|--version) + show_ver; exit 0 + ;; + -l|--iplist) + IPLIST=$2; shift 2 + ;; + -c|--config) + CONFIG_FILE=$2; shift 2 + ;; + -t|--sshtimeout) + SSHTIMEOUT=$2; shift 2 + ;; + -T|--fttimeout) + SCPTIMEOUT=$2; shift 2 + ;; + -L|--bwlimit) + BWLIMIT=$2; shift 2 + ;; + --log) + LOG_FILE=$2; shift 2 + ;; + -n|--ignore) + IGNRFLAG="ignr"; shift + ;; + --) + shift + ;; + *) + echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1 + ;; + esac +done + +################ main ####################### +BEGINDATETIME=`date "+%F %T"` +[ ! -f $IPLIST ] && echo -e "\033[31mERROR: iplist \"$IPLIST\" not exists, please check! \033[0m\n" && exit 1 + +[ ! -f $CONFIG_FILE ] && echo -e "\033[31mERROR: config \"$CONFIG_FILE\" not exists, please check! \033[0m\n" && exit 1 + +IP_count=$(egrep -v '^#|^$' $IPLIST|wc -l) +IP_init=1 +while [[ $IP_init -le $IP_count ]] +do + egrep -v '^#|^$' $IPLIST | sed -n "$IP_init,$(expr $IP_init + 50)p" > $IPLIST.tmp + + IPSEQ=0 + + while read IP PORT USER PASSWD PASSWD_2ND PASSWD_3RD PASSWD_4TH OTHERS + # while read Line + do + #[ -z "`echo $IP | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|CNS'`" ] && continue + if [ "`python ./ckssh.py $IP $PORT`" == 'no' ]; then + [ ! -e ipnologin.txt ] && > ipnologin.txt + [ -z "`grep $IP ipnologin.txt | grep $(date +%F)`" ] && echo "`date +%F_%H%M` $IP" >> ipnologin.txt + continue + fi + + #[ -e "~/.ssh/known_hosts" ] && grep $IP ~/.ssh/known_hosts | sed -i "/$IP/d" ~/.ssh/known_hosts + + let IPSEQ=$IPSEQ+1 + + if [ $IGNRFLAG == "ignr" ]; then + ignore_init + ignored_flag=0 + + i=0 + while [ $i -lt $array_ignore_pwd_length ] + do + [ ${PASSWD}x == ${array_ignore_pwd[$i]}x ] && ignored_flag=1 && break + let i=$i+1 + done + + [ $ignored_flag -eq 1 ] && continue + + j=0 + while [ $j -lt $array_ignore_ip_length ] + do + [ ${IP}x == ${array_ignore_ip[$j]}x ] && ignored_flag=1 && break + let j=$j+1 + done + + [ $ignored_flag -eq 1 ] && continue + fi + + PASSWD_USE=$PASSWD + + IPcode=$(echo "ibase=16;$(echo "$IP" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + Portcode=$(echo "ibase=16;$(echo "$PORT" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + #USER=$USER + PWcode=$(echo "ibase=16;$(echo "$PASSWD_USE" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + Othercode=$(echo "ibase=16;$(echo "$OTHERS" | xxd -ps -u)"|bc|tr -d '\\'|tr -d '\n') + #echo $IPcode $Portcode $USER $PWcode $CONFIG_FILE $SSHTIMEOUT $SCPTIMEOUT $BWLIMIT $Othercode + ./thread.sh $IPcode $Portcode $USER $PWcode $CONFIG_FILE $SSHTIMEOUT $SCPTIMEOUT $BWLIMIT $Othercode | tee logs/$IP.log & + done < $IPLIST.tmp + sleep 3 + IP_init=$(expr $IP_init + 50) +done + +ENDDATETIME=`date "+%F %T"` + +echo "$BEGINDATETIME -- $ENDDATETIME" +echo "$0 $* --excutes over!" + +exit 0 diff --git a/scripts/mscp.exp b/scripts/mscp.exp new file mode 100644 index 0000000..3a93a04 --- /dev/null +++ b/scripts/mscp.exp @@ -0,0 +1,158 @@ +#!/usr/bin/expect -- + +proc Usage_Exit {self} { + puts "" + puts "Usage: $self ip user passwd port sourcefile destdir direction bwlimit timeout" + puts "" + puts " sourcefile: a file or directory to be transferred" + puts " 需要拷贝目录时目录名后不要带 /, 否则会拷贝该目录下的所有文件" + puts " destdir: the location that the sourcefile to be put into" + puts " direction: pull or push" + puts " pull: remote -> local" + puts " push: local -> remote" + puts " bwlimit: bandwidth limit, kbit/s, 0 means no limit" + puts " timeout: timeout of expect, s, -1 means no timeout" + puts "" + exit 1 +} + +if { [llength $argv] < 9 } { + Usage_Exit $argv0 +} + +set ipcode [lindex $argv 0] +set ip [exec dc -e $ipcode] +set user [lindex $argv 1] +set passwduncode [lindex $argv 2] +set passwd [exec dc -e $passwduncode] +set portcode [lindex $argv 3] +set port [exec dc -e $portcode] +set sourcefile [lindex $argv 4] +set destdir [lindex $argv 5] +set direction [lindex $argv 6] +set bwlimit [lindex $argv 7] +set timeoutflag [lindex $argv 8] + +set yesnoflag 0 +set timeout $timeoutflag + +for {} {1} {} { + # for is only used to retry when "Interrupted system call" occured + + if { $direction == "pull" } { + + if { $bwlimit > 0 } { + spawn rsync -crazP --delete --bwlimit=$bwlimit -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $ip:$sourcefile $destdir + } elseif { $bwlimit == 0 } { + spawn rsync -crazP --delete -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $ip:$sourcefile $destdir + } else { + Usage_Exit $argv0 + } + + } elseif { $direction == "push" } { + + if { $bwlimit > 0 } { + spawn rsync -crazP --delete --bwlimit=$bwlimit -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $sourcefile $ip:$destdir + } elseif { $bwlimit == 0 } { + spawn rsync -crazP --delete -e "/usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port" $sourcefile $ip:$destdir + } else { + Usage_Exit $argv0 + } + + } else { + Usage_Exit $argv0 + } + + expect { + + "assword:" { + send "$passwd\r" + break; + } + + "yes/no" { + set yesnoflag 1 + send "yes\r" + break; + } + + "FATAL" { + puts "\nCONNECTERROR: $ip occur FATAL ERROR!!!\n" + exit 1 + } + + timeout { + puts "\nCONNECTERROR: $ip Logon timeout!!!\n" + exit 1 + } + + "No route to host" { + puts "\nCONNECTERROR: $ip No route to host!!!\n" + exit 1 + } + + "Connection Refused" { + puts "\nCONNECTERROR: $ip Connection Refused!!!\n" + exit 1 + } + + "Connection refused" { + puts "\nCONNECTERROR: $ip Connection Refused!!!\n" + exit 1 + } + + "Host key verification failed" { + puts "\nCONNECTERROR: $ip Host key verification failed!!!\n" + exit 1 + } + + "Illegal host key" { + puts "\nCONNECTERROR: $ip Illegal host key!!!\n" + exit 1 + } + + "Connection Timed Out" { + puts "\nCONNECTERROR: $ip Logon timeout!!!\n" + exit 1 + } + + "Interrupted system call" { + puts "\n$ip Interrupted system call!!!\n" + } + } + +} + +if { $yesnoflag == 1 } { + expect { + "assword:" { + send "$passwd\r" + } + + "yes/no)?" { + set yesnoflag 2 + send "yes\r" + } + } +} + +if { $yesnoflag == 2 } { + expect { + "assword:" { + send "$passwd\r" + } + } +} + +expect { + "assword:" { + send "$passwd\r" + puts "\nPASSWORDERROR: $ip Password error!!!\n" + exit 1 + } + + eof { + puts "OK_SCP: $ip\n" + exit 0; + } +} diff --git a/scripts/mssh.exp b/scripts/mssh.exp new file mode 100644 index 0000000..95eeb83 --- /dev/null +++ b/scripts/mssh.exp @@ -0,0 +1,129 @@ +#!/usr/bin/expect -- + +if { [llength $argv] < 4 } { + puts "Usage: $argv0 ip user passwd port commands timeout" + exit 1 +} + +match_max 600000 + +set ipcode [lindex $argv 0] +set ip [exec dc -e $ipcode] +set user [lindex $argv 1] +set passwdcode [lindex $argv 2] +set passwd [exec dc -e $passwdcode] +set portcode [lindex $argv 3] +set port [exec dc -e $portcode] +set commands [lindex $argv 4] +set timeoutflag [lindex $argv 5] + +set yesnoflag 0 +set timeout $timeoutflag + + +for {} {1} {} { + # for is only used to retry when "Interrupted system call" occured + + spawn /usr/bin/ssh -o GSSAPIAuthentication=no -q -l$user -p$port $ip + + expect { + + "assword:" { + send "$passwd\r" + break; + } + + "yes/no)?" { + set yesnoflag 1 + send "yes\r" + break; + } + + "FATAL" { + puts "\nCONNECTERROR: $ip occur FATAL ERROR!!!\n" + exit 1 + } + + timeout { + puts "\nCONNECTERROR: $ip Logon timeout!!!\n" + exit 1 + } + + "No route to host" { + puts "\nCONNECTERROR: $ip No route to host!!!\n" + exit 1 + } + + "Connection Refused" { + puts "\nCONNECTERROR: $ip Connection Refused!!!\n" + exit 1 + } + + "Connection refused" { + puts "\nCONNECTERROR: $ip Connection Refused!!!\n" + exit 1 + } + + "Host key verification failed" { + puts "\nCONNECTERROR: $ip Host key verification failed!!!\n" + exit 1 + } + + "Illegal host key" { + puts "\nCONNECTERROR: $ip Illegal host key!!!\n" + exit 1 + } + + "Connection Timed Out" { + puts "\nCONNECTERROR: $ip Logon timeout!!!\n" + exit 1 + } + + "Interrupted system call" { + puts "\n$ip Interrupted system call!!!\n" + } + } +} + +if { $yesnoflag == 1 } { + expect { + "assword:" { + send "$passwd\r" + } + + "yes/no" { + set yesnoflag 2 + send "yes\r" + } + } +} + +if { $yesnoflag == 2 } { + expect { + "assword:" { + send "$passwd\r" + } + } +} + +expect { + "@" {send "$commands \r"} + "assword:" { + send "$passwd\r" + puts "\nPASSWORDERROR: $ip Password error!!!\n" + exit 1 + } +} + +expect { + "@" {send "sleep 1\r"} +} + +expect { + "@" {send "exit\r"} +} + +expect eof { + puts "OK_SSH: $ip\n" + exit 0; +} diff --git a/scripts/thread.sh b/scripts/thread.sh new file mode 100644 index 0000000..27fb0dd --- /dev/null +++ b/scripts/thread.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Author: yeho +# Blog: http://linuxeye.com + +# Default Parameters +myIFS=":::" + +IP=$1P +PORT=$2P +USER=$3 +PASSWD=$4P +CONFIG_FILE=$5 +SSHTIMEOUT=$6 +SCPTIMEOUT=$7 +BWLIMIT=$8 + +while read eachline +do + [ -z "`echo $eachline | grep -E '^com|^file'`" ] && continue + + myKEYWORD=`echo $eachline | awk -F"$myIFS" '{ print $1 }'` + myCONFIGLINE=`echo $eachline | awk -F"$myIFS" '{ print $2 }'` + + if [ "$myKEYWORD"x == "file"x ]; then + SOURCEFILE=`echo $myCONFIGLINE | awk '{ print $1 }'` + DESTDIR=`echo $myCONFIGLINE | awk '{ print $2 }'` + DIRECTION=`echo $myCONFIGLINE | awk '{ print $3 }'` + ./mscp.exp $IP $USER $PASSWD $PORT $SOURCEFILE $DESTDIR $DIRECTION $BWLIMIT $SCPTIMEOUT + + [ $? -ne 0 ] && echo -e "\033[31mSCP Try Out All Password Failed\033[0m\n" + + elif [ "$myKEYWORD"x == "com"x ]; then + ./mssh.exp $IP $USER $PASSWD $PORT "${myCONFIGLINE}" $SSHTIMEOUT + [ $? -ne 0 ] && echo -e "\033[31mSSH Try Out All Password Failed\033[0m\n" + + else + echo "ERROR: configuration wrong! [$eachline] " + echo " where KEYWORD should not be [$myKEYWORD], but 'com' or 'file'" + echo " if you dont want to run it, you can comment it with '#'" + echo "" + exit + fi + +done < $CONFIG_FILE + +exit 0 diff --git a/scripts/website_bk.sh b/scripts/website_bk.sh new file mode 100644 index 0000000..d0a9ace --- /dev/null +++ b/scripts/website_bk.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Author: yeho +# BLOG: https://linuxeye.com +# +# Notes: OneinStack for CentOS/RedHat 7+ Debian 9+ and Ubuntu 16+ +# +# Project home page: +# https://oneinstack.com +# https://github.com/oneinstack/oneinstack + +. ../config/options.conf + +WebSite=$1 +LogFile=${backup_dir}/web.log +NewFile=${backup_dir}/Web_${WebSite}_$(date +%Y%m%d_%H).tgz +OldFile=${backup_dir}/Web_${WebSite}_$(date +%Y%m%d --date="${expired_days} days ago")*.tgz +[ ! -e "${backup_dir}" ] && mkdir -p ${backup_dir} +[ ! -e "${wwwroot_dir}/${WebSite}" ] && { echo "[${wwwroot_dir}/${WebSite}] not exist" >> ${LogFile} ; exit 1 ; } + +if [ `du -sm "${wwwroot_dir}/${WebSite}" | awk '{print $1}'` -lt 1024 ]; then + if [ -n "`ls ${OldFile} 2>/dev/null`" ]; then + rm -f ${OldFile} + echo "[${OldFile}] Delete Old File Success" >> ${LogFile} + else + echo "[${OldFile}] Delete Old Backup File" >> ${LogFile} + fi + + if [ -e "${NewFile}" ]; then + echo "[${NewFile}] The Backup File is exists, Can't Backup" >> ${LogFile} + else + pushd ${wwwroot_dir} > /dev/null + tar czf ${NewFile} ./${WebSite} >> ${LogFile} 2>&1 + echo "[${NewFile}] Backup success ">> ${LogFile} + popd > /dev/null + fi +else + rsync -crazP --delete ${wwwroot_dir}/${WebSite} ${backup_dir} +fi diff --git a/services/mongod.service b/services/mongod.service new file mode 100644 index 0000000..02bfe72 --- /dev/null +++ b/services/mongod.service @@ -0,0 +1,37 @@ +[Unit] +Description=MongoDB Database Server +After=multi-user.target +Documentation=https://docs.mongodb.org/manual + +[Service] +User=mongod +Group=mongod +Environment="OPTIONS=-f /etc/mongod.conf" +EnvironmentFile=-/etc/sysconfig/mongod +ExecStart=/usr/local/mongodb/bin/mongod $OPTIONS +ExecStartPre=/bin/mkdir -p /var/run/mongodb +ExecStartPre=/bin/chown mongod:mongod /var/run/mongodb +ExecStartPre=/bin/chmod 0755 /var/run/mongodb +PermissionsStartOnly=true +PIDFile=/var/run/mongodb/mongod.pid +Type=forking +# file size +LimitFSIZE=infinity +# cpu time +LimitCPU=infinity +# virtual memory size +LimitAS=infinity +# open files +LimitNOFILE=64000 +# processes/threads +LimitNPROC=64000 +# locked memory +LimitMEMLOCK=infinity +# total threads (user+kernel) +TasksMax=infinity +TasksAccounting=false +# Recommended limits for for mongod as specified in +# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings + +[Install] +WantedBy=multi-user.target diff --git a/services/nginx.service b/services/nginx.service new file mode 100644 index 0000000..79e3988 --- /dev/null +++ b/services/nginx.service @@ -0,0 +1,20 @@ +[Unit] +Description=nginx - high performance web server +Documentation=http://nginx.org/en/docs/ +After=network.target + +[Service] +Type=forking +PIDFile=/var/run/nginx.pid +ExecStartPost=/bin/sleep 0.1 +ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf +ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s QUIT $MAINPID +TimeoutStartSec=120 +LimitNOFILE=1000000 +LimitNPROC=1000000 +LimitCORE=1000000 + +[Install] +WantedBy=multi-user.target diff --git a/services/php-fpm.service b/services/php-fpm.service new file mode 100644 index 0000000..6538a50 --- /dev/null +++ b/services/php-fpm.service @@ -0,0 +1,16 @@ +[Unit] +Description=The PHP FastCGI Process Manager +Documentation=http://php.net/docs.php +After=network.target + +[Service] +Type=simple +PIDFile=/usr/local/php/var/run/php-fpm.pid +ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf +ExecReload=/bin/kill -USR2 $MAINPID +LimitNOFILE=1000000 +LimitNPROC=1000000 +LimitCORE=1000000 + +[Install] +WantedBy=multi-user.target diff --git a/services/postgresql.service b/services/postgresql.service new file mode 100644 index 0000000..107ff5f --- /dev/null +++ b/services/postgresql.service @@ -0,0 +1,39 @@ +[Unit] +Description=PostgreSQL database server +After=network.target + +[Service] +Type=forking + +User=postgres +Group=postgres + +# Where to send early-startup messages from the server (before the logging +# options of postgresql.conf take effect) +# This is normally controlled by the global default set by systemd +# StandardOutput=syslog + +# Disable OOM kill on the postmaster +OOMScoreAdjust=-1000 +# ... but allow it still to be effective for child processes +# (note that these settings are ignored by Postgres releases before 9.5) +Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj +Environment=PG_OOM_ADJUST_VALUE=0 + +# Maximum number of seconds pg_ctl will wait for postgres to start. Note that +# PGSTARTTIMEOUT should be less than TimeoutSec value. +Environment=PGSTARTTIMEOUT=270 + +Environment=PGDATA=/data/pgsql + +ExecStart=/usr/local/pgsql/bin/pg_ctl start -D ${PGDATA} -s -w -t ${PGSTARTTIMEOUT} +ExecStop=/usr/local/pgsql/bin/pg_ctl stop -D ${PGDATA} -s -m fast +ExecReload=/usr/local/pgsql/bin/pg_ctl reload -D ${PGDATA} -s + +# Give a reasonable amount of time for the server to start up/shut down. +# Ideally, the timeout for starting PostgreSQL server should be handled more +# nicely by pg_ctl in ExecStart, so keep its timeout smaller than this value. +TimeoutSec=300 + +[Install] +WantedBy=multi-user.target diff --git a/services/pureftpd.service b/services/pureftpd.service new file mode 100644 index 0000000..31bb779 --- /dev/null +++ b/services/pureftpd.service @@ -0,0 +1,11 @@ +[Unit] +Description=Pure-FTPd FTP server +After=network.target + +[Service] +Type=forking +PIDFile=/var/run/pure-ftpd.pid +ExecStart=/usr/local/pureftpd/sbin/pure-ftpd /usr/local/pureftpd/etc/pure-ftpd.conf + +[Install] +WantedBy=multi-user.target diff --git a/services/redis-server.service b/services/redis-server.service new file mode 100644 index 0000000..cf67b4c --- /dev/null +++ b/services/redis-server.service @@ -0,0 +1,23 @@ +[Unit] +Description=Redis In-Memory Data Store +After=network.target + +[Service] +Type=forking +PIDFile=/var/run/redis/redis.pid +User=redis +Group=redis + +Environment=statedir=/var/run/redis +PermissionsStartOnly=true +ExecStartPre=/bin/mkdir -p ${statedir} +ExecStartPre=/bin/chown -R redis:redis ${statedir} +ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf +ExecStop=/bin/kill -s TERM $MAINPID +Restart=always +LimitNOFILE=1000000 +LimitNPROC=1000000 +LimitCORE=1000000 + +[Install] +WantedBy=multi-user.target diff --git a/src/adoptium.key b/src/adoptium.key new file mode 100644 index 0000000..7d76f7a --- /dev/null +++ b/src/adoptium.key @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBGGTvTQBCAC6ey144n7CG8foafF6mwgIBN1fIm1ILZDuGS4tMr0/XI8pgJnT +QvsPxZWEvtSm7bEMObzEoZJcXwjBcJl1B0ui8k5kHMTI75gCmZPsoKLFWIEpuRBQ +PBocusw80apDmLnNDQLVQvDFtEua5gaNa/fRw9YsmBoXBqvgrjFUIdGyWoQvH5+a +9OYlWD9n5VV0gnVMb+aclwVzB/zJw3kHGSgzuMtlAHeQiah7Y8yomQn/UIX8yqDf ++11sP3+c87YcjkRqImRTtmKEDcEtGPAIXC6SYA+uEEkbYE0Fy0chkvtnVWJ597fa +Epai4rnICU8zoJ6X5z3v1aM2WerhX9oq9X8PABEBAAG0QEFkb3B0aXVtIEdQRyBL +ZXkgKERFQi9SUE0gU2lnbmluZyBLZXkpIDx0ZW11cmluLWRldkBlY2xpcHNlLm9y +Zz6JAVIEEwEIADwWIQQ7BNdTyQUNml00PzmEPEilZfjwSwUCYZO9NAIbAwULCQgH +AgMiAgEGFQoJCAsCBBYCAwECHgcCF4AACgkQhDxIpWX48Et4AggAjjJzYWuKV3nG +7ngInngl8G/m9JoHr7BmwgcQXYhdy5hVkMcUx5JLeXz2LMBUH/F2nD595hgjMabk +kVib20X8lq9RsNbdfc2hBcWU6qyHKxsIqT4boI2/XDyEzzMyyZWWNGo/27Ci7Xmj +pWu31nh0pDdPqdyWDIKojbVVnxlCRY8as8Sm+1ufi709KCi4MuwHNsUlCSwb/fju +NKeHkrHbLcHKUUIEcmTSKRWrpMYBzm1HYOGBz4xPuELwUfUp71ehfoyBZlp6RDRf +l5TYI1FmCyHuvjNhrJgWv7bOTcf8yObGY+TEUhzc4xQqCrF4ur9d3opvsuPBQsv+ +Klqi5KSZgrkBDQRhk700AQgAq14okly8cFrpYVenEQPiB75AUZfKRpMduiR6IxAj +SKcH7aSoFZ9AubUEBVpZsyT5svxoEPe1i4TdbF+m9FGy42EcOlLa3ArLTj5H8FRl +UdGZB9I5mk4GptOzPM+aHMMu92vW/ZwjuS8DvOiQSp+cUmG1EqOMJSM7e/4BM71z +E+OKaVJCj79pEzhG3SK/IC/OlxxyETT66NSfYJd7Sw5R6Vr19am/uNU690W0CJ+q +VQeFpmDMr7LnfdFRIh+lJe05+PvWXeidkGjox5cbG52wf8aRIR/FgkfcFvqRMN1f +B+dVOWueloUeVAnzcUznOKmUEs7LP9ObJhYHHgup4IAU2wARAQABiQE2BBgBCAAg +FiEEOwTXU8kFDZpdND85hDxIpWX48EsFAmGTvTQCGwwACgkQhDxIpWX48EvXHQf/ +Q0nZsGDXnZHiBoojeSdpkO7WBjMIP3w1GdLvRpPQrS8TfOPbZuoevzCNh38Y3gwF +yelJspvzDQrBXhgkzAGlucYg8Y7KHa5Ebm7iDgMzc37L1hYSZTYCqwd7aowfgy34 +hOk3B67LffkJpIh738Oa9CtlwxQ9xcytmBmQ1fBBOwm/9IhAwHPQuydYIs4DxWbj +0MGSP4fDntU7e4UjsHNmhudDcYol0FaqdHHIIB9C/G4CzetRwHFOn3b4JwXMU7YU +6aJA3mXhi3hggMC3wkT2HHZ/TquuOdNc02fypWOCDOHz0alBBJNqoVUNFNqU3tfJ +wI4qF/KKq9BfyfucAs0ykA== +=szki +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/src/libiconv-glibc-2.16.patch b/src/libiconv-glibc-2.16.patch new file mode 100644 index 0000000..1703cb8 --- /dev/null +++ b/src/libiconv-glibc-2.16.patch @@ -0,0 +1,11 @@ +--- srclib/stdio.in.h.orig 2011-08-07 16:42:06.000000000 +0300 ++++ srclib/stdio.in.h 2013-01-10 15:53:03.000000000 +0200 +@@ -695,7 +695,9 @@ + /* It is very rare that the developer ever has full control of stdin, + so any use of gets warrants an unconditional warning. Assume it is + always declared, since it is required by C89. */ +-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); ++#if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16) ++ _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); ++#endif + #endif diff --git a/src/libmemcached-build.patch b/src/libmemcached-build.patch new file mode 100644 index 0000000..df58c9f --- /dev/null +++ b/src/libmemcached-build.patch @@ -0,0 +1,21 @@ +diff -up ./clients/memflush.cc.old ./clients/memflush.cc +--- ./clients/memflush.cc.old 2017-02-12 10:12:59.615209225 +0100 ++++ ./clients/memflush.cc 2017-02-12 10:13:39.998382783 +0100 +@@ -39,7 +39,7 @@ int main(int argc, char *argv[]) + { + options_parse(argc, argv); + +- if (opt_servers == false) ++ if (!opt_servers) + { + char *temp; + +@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) + opt_servers= strdup(temp); + } + +- if (opt_servers == false) ++ if (!opt_servers) + { + std::cerr << "No Servers provided" << std::endl; + exit(EXIT_FAILURE); diff --git a/src/php5.3patch b/src/php5.3patch new file mode 100644 index 0000000..285299d --- /dev/null +++ b/src/php5.3patch @@ -0,0 +1,80 @@ +diff --git a/main/rfc1867.c b/main/rfc1867.c +index b3f94ec..7613119 100644 +--- a/main/rfc1867.c ++++ b/main/rfc1867.c +@@ -33,6 +33,8 @@ + #include "php_variables.h" + #include "rfc1867.h" + #include "ext/standard/php_string.h" ++#include "ext/standard/php_smart_str.h" ++ + + #define DEBUG_FILE_UPLOAD ZEND_DEBUG + +@@ -462,6 +464,66 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) + static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) + { + char *line; ++ mime_header_entry entry = {0}; ++ smart_str buf_value = {0}; ++ char *key = NULL; ++ ++ /* didn't find boundary, abort */ ++ if (!find_boundary(self, self->boundary TSRMLS_CC)) { ++ return 0; ++ } ++ ++ /* get lines of text, or CRLF_CRLF */ ++ ++ while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) ++ { ++ /* add header to table */ ++ char *value = NULL; ++ ++ /*if (php_rfc1867_encoding_translation(TSRMLS_C)) { ++ //self->input_encoding = zend_multibyte_encoding_detector((unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC); ++ }*/ ++ ++ /* space in the beginning means same header */ ++ if (!isspace(line[0])) { ++ value = strchr(line, ':'); ++ } ++ ++ if (value) { ++ if(buf_value.c && key) { ++ /* new entry, add the old one to the list */ ++ smart_str_0(&buf_value); ++ entry.key = key; ++ entry.value = buf_value.c; ++ zend_llist_add_element(header, &entry); ++ buf_value.c = NULL; ++ key = NULL; ++ } ++ ++ *value = '\0'; ++ do { value++; } while(isspace(*value)); ++ ++ key = estrdup(line); ++ smart_str_appends(&buf_value, value); ++ } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ ++ smart_str_appends(&buf_value, line); ++ } else { ++ continue; ++ } ++ } ++ if(buf_value.c && key) { ++ /* add the last one to the list */ ++ smart_str_0(&buf_value); ++ entry.key = key; ++ entry.value = buf_value.c; ++ zend_llist_add_element(header, &entry); ++ } ++ ++ return 1; ++} ++static int multipart_buffer_headers_bak(multipart_buffer *self, zend_llist *header TSRMLS_DC) ++{ ++ char *line; + mime_header_entry prev_entry, entry; + int prev_len, cur_len; + diff --git a/templates/cloudflare.conf b/templates/cloudflare.conf new file mode 100644 index 0000000..ac462ea --- /dev/null +++ b/templates/cloudflare.conf @@ -0,0 +1,25 @@ +set_real_ip_from 103.21.244.0/22; +set_real_ip_from 103.22.200.0/22; +set_real_ip_from 103.31.4.0/22; +set_real_ip_from 104.16.0.0/12; +set_real_ip_from 108.162.192.0/18; +set_real_ip_from 131.0.72.0/22; +set_real_ip_from 141.101.64.0/18; +set_real_ip_from 162.158.0.0/15; +set_real_ip_from 172.64.0.0/13; +set_real_ip_from 173.245.48.0/20; +set_real_ip_from 188.114.96.0/20; +set_real_ip_from 190.93.240.0/20; +set_real_ip_from 197.234.240.0/22; +set_real_ip_from 198.41.128.0/17; +set_real_ip_from 2400:cb00::/32; +set_real_ip_from 2606:4700::/32; +set_real_ip_from 2803:f800::/32; +set_real_ip_from 2405:b500::/32; +set_real_ip_from 2405:8100::/32; +set_real_ip_from 2c0f:f248::/32; +set_real_ip_from 2a06:98c0::/29; + +# use any of the following two +real_ip_header CF-Connecting-IP; +#real_ip_header X-Forwarded-For; diff --git a/templates/codeigniter.conf b/templates/codeigniter.conf new file mode 100644 index 0000000..ac112d4 --- /dev/null +++ b/templates/codeigniter.conf @@ -0,0 +1,3 @@ +location / { + try_files $uri $uri/ /index.php?/$request_uri; +} diff --git a/templates/discuz.conf b/templates/discuz.conf new file mode 100644 index 0000000..d3166e9 --- /dev/null +++ b/templates/discuz.conf @@ -0,0 +1,12 @@ +rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; +rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; +rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; +rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; +rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; +rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; +rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last; +rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last; +rewrite ^([^\.]*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3 last; +#if (!-e $request_filename) { +# return 404; +#} diff --git a/templates/drupal.conf b/templates/drupal.conf new file mode 100644 index 0000000..a4de4e9 --- /dev/null +++ b/templates/drupal.conf @@ -0,0 +1,4 @@ +if (!-e $request_filename) { + rewrite ^/update.php(.*)$ /update.php?q=$1 last; + rewrite ^/(.*)$ /index.php?q=$1 last; +} diff --git a/templates/ecshop.conf b/templates/ecshop.conf new file mode 100644 index 0000000..25bc858 --- /dev/null +++ b/templates/ecshop.conf @@ -0,0 +1,31 @@ +if (!-e $request_filename) { + rewrite "^/index\.html" /index.php last; + rewrite "^/category$" /index.php last; + rewrite "^/feed-c([0-9]+)\.xml$" /feed.php?cat=$1 last; + rewrite "^/feed-b([0-9]+)\.xml$" /feed.php?brand=$1 last; + rewrite "^/feed\.xml$" /feed.php last; + rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8 last; + rewrite "^/category-([0-9]+)-b([0-9]+)-min([0-9]+)-max([0-9]+)-attr([^-]*)(.*)\.html$" /category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5 last; + rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3&sort=$4&order=$5 last; + rewrite "^/category-([0-9]+)-b([0-9]+)-([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2&page=$3 last; + rewrite "^/category-([0-9]+)-b([0-9]+)(.*)\.html$" /category.php?id=$1&brand=$2 last; + rewrite "^/category-([0-9]+)(.*)\.html$" /category.php?id=$1 last; + rewrite "^/goods-([0-9]+)(.*)\.html" /goods.php?id=$1 last; + rewrite "^/article_cat-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /article_cat.php?id=$1&page=$2&sort=$3&order=$4 last; + rewrite "^/article_cat-([0-9]+)-([0-9]+)(.*)\.html$" /article_cat.php?id=$1&page=$2 last; + rewrite "^/article_cat-([0-9]+)(.*)\.html$" /article_cat.php?id=$1 last; + rewrite "^/article-([0-9]+)(.*)\.html$" /article.php?id=$1 last; + rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)\.html" /brand.php?id=$1&cat=$2&page=$3&sort=$4&order=$5 last; + rewrite "^/brand-([0-9]+)-c([0-9]+)-([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2&page=$3 last; + rewrite "^/brand-([0-9]+)-c([0-9]+)(.*)\.html" /brand.php?id=$1&cat=$2 last; + rewrite "^/brand-([0-9]+)(.*)\.html" /brand.php?id=$1 last; + rewrite "^/tag-(.*)\.html" /search.php?keywords=$1 last; + rewrite "^/snatch-([0-9]+)\.html$" /snatch.php?id=$1 last; + rewrite "^/group_buy-([0-9]+)\.html$" /group_buy.php?act=view&id=$1 last; + rewrite "^/auction-([0-9]+)\.html$" /auction.php?act=view&id=$1 last; + rewrite "^/exchange-id([0-9]+)(.*)\.html$" /exchange.php?id=$1&act=view last; + rewrite "^/exchange-([0-9]+)-min([0-9]+)-max([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&integral_min=$2&integral_max=$3&page=$4&sort=$5&order=$6 last; + rewrite "^/exchange-([0-9]+)-([0-9]+)-(.+)-([a-zA-Z]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2&sort=$3&order=$4 last; + rewrite "^/exchange-([0-9]+)-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1&page=$2 last; + rewrite "^/exchange-([0-9]+)(.*)\.html$" /exchange.php?cat_id=$1 last; +} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..2da911a --- /dev/null +++ b/templates/index.html @@ -0,0 +1,304 @@ + + + + + 404 + + + + + + +
+ +
+

系统调试中 ~

休息一会儿,马上回来! (灬ꈍ ꈍ灬)

+ +
+
+
+
404
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/templates/index_cn.html b/templates/index_cn.html new file mode 100644 index 0000000..2da911a --- /dev/null +++ b/templates/index_cn.html @@ -0,0 +1,304 @@ + + + + + 404 + + + + + + +
+ +
+

系统调试中 ~

休息一会儿,马上回来! (灬ꈍ ꈍ灬)

+ +
+
+
+
404
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/templates/joomla.conf b/templates/joomla.conf new file mode 100644 index 0000000..2af92c0 --- /dev/null +++ b/templates/joomla.conf @@ -0,0 +1,3 @@ +location / { + try_files $uri $uri/ /index.php?$args; +} diff --git a/templates/laravel.conf b/templates/laravel.conf new file mode 100644 index 0000000..4b488fd --- /dev/null +++ b/templates/laravel.conf @@ -0,0 +1,3 @@ +location / { + try_files $uri $uri/ /index.php?$query_string; +} diff --git a/templates/magento2.conf b/templates/magento2.conf new file mode 100644 index 0000000..35e18c1 --- /dev/null +++ b/templates/magento2.conf @@ -0,0 +1,171 @@ +server { + listen 80; + server_name oneinstack.com; + set $MAGE_ROOT /data/wwwroot/default; + root $MAGE_ROOT/pub; + index index.php; + autoindex off; + charset UTF-8; + error_page 404 403 /errors/404.php; + #add_header "X-UA-Compatible" "IE=Edge"; + + # PHP entry point for setup application + location ~* ^/setup($|/) { + root $MAGE_ROOT; + location ~ ^/setup/index.php { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ ^/setup/(?!pub/). { + deny all; + } + + location ~ ^/setup/pub/ { + add_header X-Frame-Options "SAMEORIGIN"; + } + } + + # PHP entry point for update application + location ~* ^/update($|/) { + root $MAGE_ROOT; + location ~ ^/update/index.php { + fastcgi_split_path_info ^(/update/index.php)(/.+)$; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + include fastcgi_params; + } + + # Deny everything but index.php + location ~ ^/update/(?!pub/). { + deny all; + } + + location ~ ^/update/pub/ { + add_header X-Frame-Options "SAMEORIGIN"; + } + } + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location /pub/ { + location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) { + deny all; + } + alias $MAGE_ROOT/pub/; + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /static/ { + # Uncomment the following line in production mode + # expires max; + # Remove signature of the static files that is used to overcome the browser cache + location ~ ^/static/version { + rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/ { + try_files $uri $uri/ /get.php?$args; + location ~ ^/media/theme_customization/.*\.xml { + deny all; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + try_files $uri $uri/ /get.php?$args; + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + try_files $uri $uri/ /get.php?$args; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/customer/ { + deny all; + } + + location /media/downloadable/ { + deny all; + } + + location /media/import/ { + deny all; + } + + # PHP entry point for main application + location ~ (index|get|static|report|404|503)\.php$ { + try_files $uri =404; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_buffers 1024 4k; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=600"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + gzip on; + gzip_disable "msie6"; + gzip_comp_level 6; + gzip_min_length 1100; + gzip_buffers 16 8k; + gzip_proxied any; + gzip_types + text/plain + text/css + text/js + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + image/svg+xml; + gzip_vary on; + + # Banned locations (only reached if the earlier PHP entry point regexes don't match) + location ~* (\.php$|\.htaccess$|\.git) { + deny all; + } +} diff --git a/templates/nextcloud.conf b/templates/nextcloud.conf new file mode 100644 index 0000000..ca6eed8 --- /dev/null +++ b/templates/nextcloud.conf @@ -0,0 +1,82 @@ +#(可选)添加如下header主要为了安全 +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block"; +add_header X-Robots-Tag none; +add_header X-Download-Options noopen; +add_header X-Permitted-Cross-Domain-Policies none; + +#(可选)为了支持user_webfinger app +rewrite ^/.well-known/host-meta /public.php?service=host-meta last; +rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last; + +#这儿是为了支持日历和联系人,建议加上 +location = /.well-known/carddav { + return 301 $scheme://$host/remote.php/dav; +} +location = /.well-known/caldav { + return 301 $scheme://$host/remote.php/dav; +} + +#设置上传文件的最大大小(还和php里的那个设置有关) +client_max_body_size 512M; +fastcgi_buffers 64 4K; + +#最主要的,将所有请求转发到index.php上 +location / { + rewrite ^ /index.php$uri; +} + +#安全设置,禁止访问部分敏感内容 +location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ { + deny all; +} +location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { + deny all; +} + +#这部分吧,默认就有,不过有所不同,所以我合并了下,替换原来的就行 +location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) { + fastcgi_split_path_info ^(.+\.php)(/.*)$; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param modHeadersAvailable true; + fastcgi_param front_controller_active true; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + include fastcgi.conf; +} + +#安全设置,禁止访问部分敏感内容 +location ~ ^/(?:updater|ocs-provider)(?:$|/) { + try_files $uri/ =404; + index index.php; +} + +location ~ \.(?:css|js|woff|svg|gif)$ { + try_files $uri /index.php$uri$is_args$args; + add_header Cache-Control "public, max-age=15778463"; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + access_log off; +} + +location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ { + try_files $uri /index.php$uri$is_args$args; + access_log off; +} + +location = /robots.txt { + allow all; + log_not_found off; + access_log off; +} + +gzip on; +gzip_vary on; +gzip_comp_level 4; +gzip_min_length 256; +gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; +gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; diff --git a/templates/nginx.conf b/templates/nginx.conf new file mode 100644 index 0000000..8e72207 --- /dev/null +++ b/templates/nginx.conf @@ -0,0 +1,123 @@ +user www www; +worker_processes auto; + +error_log /data/wwwlogs/error_nginx.log crit; +pid /var/run/nginx.pid; +worker_rlimit_nofile 51200; + +events { + use epoll; + worker_connections 51200; + multi_accept on; +} + +http { + include mime.types; + default_type application/octet-stream; + server_names_hash_bucket_size 128; + client_header_buffer_size 32k; + large_client_header_buffers 4 32k; + client_max_body_size 1024m; + client_body_buffer_size 10m; + sendfile on; + tcp_nopush on; + keepalive_timeout 120; + server_tokens off; + tcp_nodelay on; + + fastcgi_connect_timeout 300; + fastcgi_send_timeout 300; + fastcgi_read_timeout 300; + fastcgi_buffer_size 64k; + fastcgi_buffers 4 64k; + fastcgi_busy_buffers_size 128k; + fastcgi_temp_file_write_size 128k; + fastcgi_intercept_errors on; + + #Gzip Compression + gzip on; + gzip_buffers 16 8k; + gzip_comp_level 6; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_proxied any; + gzip_vary on; + gzip_types + text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml + text/javascript application/javascript application/x-javascript + text/x-json application/json application/x-web-app-manifest+json + text/css text/plain text/x-component + font/opentype application/x-font-ttf application/vnd.ms-fontobject + image/x-icon; + gzip_disable "MSIE [1-6]\.(?!.*SV1)"; + + ##Brotli Compression + #brotli on; + #brotli_comp_level 6; + #brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml; + + ##If you have a lot of static files to serve through Nginx then caching of the files' metadata (not the actual files' contents) can save some latency. + #open_file_cache max=1000 inactive=20s; + #open_file_cache_valid 30s; + #open_file_cache_min_uses 2; + #open_file_cache_errors on; + + log_format json escape=json '{"@timestamp":"$time_iso8601",' + '"server_addr":"$server_addr",' + '"remote_addr":"$remote_addr",' + '"scheme":"$scheme",' + '"request_method":"$request_method",' + '"request_uri": "$request_uri",' + '"request_length": "$request_length",' + '"uri": "$uri", ' + '"request_time":$request_time,' + '"body_bytes_sent":$body_bytes_sent,' + '"bytes_sent":$bytes_sent,' + '"status":"$status",' + '"upstream_time":"$upstream_response_time",' + '"upstream_host":"$upstream_addr",' + '"upstream_status":"$upstream_status",' + '"host":"$host",' + '"http_referer":"$http_referer",' + '"http_user_agent":"$http_user_agent"' + '}'; + +######################## default ############################ + server { + listen 80; + server_name _; + access_log /data/wwwlogs/access_nginx.log combined; + root /data/wwwroot/default; + index index.html index.htm index.php; + #error_page 404 /404.html; + #error_page 502 /502.html; + location /nginx_status { + stub_status on; + access_log off; + allow 127.0.0.1; + deny all; + } + location ~ [^/]\.php(/|$) { + #fastcgi_pass remote_php_ip:9000; + fastcgi_pass unix:/dev/shm/php-cgi.sock; + fastcgi_index index.php; + include fastcgi.conf; + } + location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)$ { + expires 30d; + access_log off; + } + location ~ .*\.(js|css)?$ { + expires 7d; + access_log off; + } + location ~ ^/(\.user.ini|\.ht|\.git|\.svn|\.project|LICENSE|README.md) { + deny all; + } + location /.well-known { + allow all; + } + } +########################## vhost ############################# + include vhost/*.conf; +} diff --git a/templates/opencart.conf b/templates/opencart.conf new file mode 100644 index 0000000..d52b219 --- /dev/null +++ b/templates/opencart.conf @@ -0,0 +1,13 @@ +location = /sitemap.xml { + rewrite ^(.*)$ /index.php?route=feed/google_sitemap break; +} +location = /googlebase.xml { + rewrite ^(.*)$ /index.php?route=feed/google_base break; +} +location / { + # This try_files directive is used to enable SEO-friendly URLs for OpenCart + try_files $uri $uri/ @opencart; +} +location @opencart { + rewrite ^/(.+)$ /index.php?_route_=$1 last; +} diff --git a/templates/pure-ftpd.conf b/templates/pure-ftpd.conf new file mode 100644 index 0000000..a9dd557 --- /dev/null +++ b/templates/pure-ftpd.conf @@ -0,0 +1,444 @@ + +############################################################ +# # +# Configuration file for pure-ftpd wrappers # +# # +############################################################ + +# If you want to run Pure-FTPd with this configuration +# instead of command-line options, please run the +# following command : +# +# /usr/local/pureftpd/sbin/pure-config.pl /usr/local/pureftpd/etc/pure-ftpd.conf +# +# Please don't forget to have a look at documentation at +# http://www.pureftpd.org/documentation.shtml for a complete list of +# options. + +# Cage in every user in his home directory + +ChrootEveryone yes + + + +# If the previous option is set to "no", members of the following group +# won't be caged. Others will be. If you don't want chroot()ing anyone, +# just comment out ChrootEveryone and TrustedGID. + +# TrustedGID 100 + + + +# Turn on compatibility hacks for broken clients + +BrokenClientsCompatibility no + + + +# Maximum number of simultaneous users + +MaxClientsNumber 5000 + + + +# Fork in background + +Daemonize yes + + + +# Maximum number of sim clients with the same IP address + +MaxClientsPerIP 500 + + + +# If you want to log all client commands, set this to "yes". +# This directive can be duplicated to also log server responses. + +VerboseLog no + + + +# List dot-files even when the client doesn't send "-a". + +DisplayDotFiles yes + + + +# Don't allow authenticated users - have a public anonymous FTP only. + +AnonymousOnly no + + + +# Disallow anonymous connections. Only allow authenticated users. + +NoAnonymous yes + + + +# Syslog facility (auth, authpriv, daemon, ftp, security, user, local*) +# The default facility is "ftp". "none" disables logging. + +SyslogFacility ftp + + + +# Display fortune cookies + +# FortunesFile /usr/share/fortune/zippy + + + +# Don't resolve host names in log files. Logs are less verbose, but +# it uses less bandwidth. Set this to "yes" on very busy servers or +# if you don't have a working DNS. + +DontResolve yes + + + +# Maximum idle time in minutes (default = 15 minutes) + +MaxIdleTime 15 + + + +# LDAP configuration file (see README.LDAP) + +# LDAPConfigFile /etc/pureftpd-ldap.conf + + + +# MySQL configuration file (see README.MySQL) + +# MySQLConfigFile /usr/local/pureftpd/etc/pureftpd-mysql.conf + + +# Postgres configuration file (see README.PGSQL) + +# PGSQLConfigFile /etc/pureftpd-pgsql.conf + + +# PureDB user database (see README.Virtual-Users) + +PureDB /usr/local/pureftpd/etc/pureftpd.pdb + + +# Path to pure-authd socket (see README.Authentication-Modules) + +# ExtAuth /var/run/ftpd.sock + + + +# If you want to enable PAM authentication, uncomment the following line + +# PAMAuthentication yes + + + +# If you want simple Unix (/etc/passwd) authentication, uncomment this + +UnixAuthentication yes + + + +# Please note that LDAPConfigFile, MySQLConfigFile, PAMAuthentication and +# UnixAuthentication can be used only once, but they can be combined +# together. For instance, if you use MySQLConfigFile, then UnixAuthentication, +# the SQL server will be asked. If the SQL authentication fails because the +# user wasn't found, another try # will be done with /etc/passwd and +# /etc/shadow. If the SQL authentication fails because the password was wrong, +# the authentication chain stops here. Authentication methods are chained in +# the order they are given. + + + +# 'ls' recursion limits. The first argument is the maximum number of +# files to be displayed. The second one is the max subdirectories depth + +LimitRecursion 2000 8 + + + +# Are anonymous users allowed to create new directories ? + +AnonymousCanCreateDirs no + + + +# If the system is more loaded than the following value, +# anonymous users aren't allowed to download. + +MaxLoad 4 + + + +# Port range for passive connections replies. - for firewalling. + +PassivePortRange 20000 30000 + + + +# Force an IP address in PASV/EPSV/SPSV replies. - for NAT. +# Symbolic host names are also accepted for gateways with dynamic IP +# addresses. + +# ForcePassiveIP 192.168.0.1 + + + +# Upload/download ratio for anonymous users. + +# AnonymousRatio 1 10 + + + +# Upload/download ratio for all users. +# This directive superscedes the previous one. + +# UserRatio 1 10 + + + +# Disallow downloading of files owned by "ftp", ie. +# files that were uploaded but not validated by a local admin. + +AntiWarez yes + + + +# IP address/port to listen to (default=all IP and port 21). + +# Bind 127.0.0.1,21 + + + +# Maximum bandwidth for anonymous users in KB/s + +# AnonymousBandwidth 8 + + + +# Maximum bandwidth for *all* users (including anonymous) in KB/s +# Use AnonymousBandwidth *or* UserBandwidth, both makes no sense. + +# UserBandwidth 8 + + + +# File creation mask. : . +# 177:077 if you feel paranoid. + +Umask 133:022 + + + +# Minimum UID for an authenticated user to log in. + +MinUID 100 + + + +# Allow FXP transfers for authenticated users. + +AllowUserFXP no + + + +# Allow anonymous FXP for anonymous and non-anonymous users. + +AllowAnonymousFXP no + + + +# Users can't delete/write files beginning with a dot ('.') +# even if they own them. If TrustedGID is enabled, this group +# will have access to dot-files, though. + +ProhibitDotFilesWrite no + + + +# Prohibit *reading* of files beginning with a dot (.history, .ssh...) + +ProhibitDotFilesRead no + + + +# Never overwrite files. When a file whoose name already exist is uploaded, +# it get automatically renamed to file.1, file.2, file.3, ... + +AutoRename no + + + +# Disallow anonymous users to upload new files (no = upload is allowed) + +AnonymousCantUpload no + + + +# Only connections to this specific IP address are allowed to be +# non-anonymous. You can use this directive to open several public IPs for +# anonymous FTP, and keep a private firewalled IP for remote administration. +# You can also only allow a non-routable local IP (like 10.x.x.x) to +# authenticate, and keep a public anon-only FTP server on another IP. + +#TrustedIP 10.1.1.1 + + + +# If you want to add the PID to every logged line, uncomment the following +# line. + +#LogPID yes + + + +# Create an additional log file with transfers logged in a Apache-like format : +# fw.c9x.org - jedi [13/Dec/1975:19:36:39] "GET /ftp/linux.tar.bz2" 200 21809338 +# This log file can then be processed by www traffic analyzers. + +# AltLog clf:/var/log/pureftpd.log + + + +# Create an additional log file with transfers logged in a format optimized +# for statistic reports. + +# AltLog stats:/var/log/pureftpd.log + + + +# Create an additional log file with transfers logged in the standard W3C +# format (compatible with most commercial log analyzers) + +# AltLog w3c:/var/log/pureftpd.log + + + +# Disallow the CHMOD command. Users can't change perms of their files. + +#NoChmod yes + + + +# Allow users to resume and upload files, but *NOT* to delete them. + +#KeepAllFiles yes + + + +# Automatically create home directories if they are missing + +CreateHomeDir no + + + +# Enable virtual quotas. The first number is the max number of files. +# The second number is the max size of megabytes. +# So 1000:10 limits every user to 1000 files and 10 Mb. + +#Quota 1000:10 + + + +# If your pure-ftpd has been compiled with standalone support, you can change +# the location of the pid file. The default is /var/run/pure-ftpd.pid + +#PIDFile /var/run/pure-ftpd.pid + + + +# If your pure-ftpd has been compiled with pure-uploadscript support, +# this will make pure-ftpd write info about new uploads to +# /var/run/pure-ftpd.upload.pipe so pure-uploadscript can read it and +# spawn a script to handle the upload. + +#CallUploadScript yes + + + +# This option is useful with servers where anonymous upload is +# allowed. As /var/ftp is in /var, it save some space and protect +# the log files. When the partition is more that X percent full, +# new uploads are disallowed. + +MaxDiskUsage 99 + + + +# Set to 'yes' if you don't want your users to rename files. + +#NoRename yes + + + +# Be 'customer proof' : workaround against common customer mistakes like +# 'chmod 0 public_html', that are valid, but that could cause ignorant +# customers to lock their files, and then keep your technical support busy +# with silly issues. If you're sure all your users have some basic Unix +# knowledge, this feature is useless. If you're a hosting service, enable it. + +CustomerProof yes + + + +# Per-user concurrency limits. It will only work if the FTP server has +# been compiled with --with-peruserlimits (and this is the case on +# most binary distributions) . +# The format is : : +# For instance, 3:20 means that the same authenticated user can have 3 active +# sessions max. And there are 20 anonymous sessions max. + +# PerUserLimits 3:20 + + + +# When a file is uploaded and there is already a previous version of the file +# with the same name, the old file will neither get removed nor truncated. +# Upload will take place in a temporary file and once the upload is complete, +# the switch to the new version will be atomic. For instance, when a large PHP +# script is being uploaded, the web server will still serve the old version and +# immediatly switch to the new one as soon as the full file will have been +# transfered. This option is incompatible with virtual quotas. + +# NoTruncate yes + + + +# This option can accept three values : +# 0 : disable SSL/TLS encryption layer (default). +# 1 : accept both traditional and encrypted sessions. +# 2 : refuse connections that don't use SSL/TLS security mechanisms, +# including anonymous sessions. +# Do _not_ uncomment this blindly. Be sure that : +# 1) Your server has been compiled with SSL/TLS support (--with-tls), +# 2) A valid certificate is in place, +# 3) Only compatible clients will log in. + +# TLS 1 + + + +# Listen only to IPv4 addresses in standalone mode (ie. disable IPv6) +# By default, both IPv4 and IPv6 are enabled. + +# IPV4Only yes + + + +# Listen only to IPv6 addresses in standalone mode (ie. disable IPv4) +# By default, both IPv4 and IPv6 are enabled. + +# IPV6Only yes + +# UTF-8 support for file names (RFC 2640) +# Define charset of the server filesystem and optionnally the default charset +# for remote clients if they don't use UTF-8. +# Works only if pure-ftpd has been compiled with --with-rfc2640 + +# FileSystemCharset big5 +# ClientCharset big5 diff --git a/templates/thinkphp.conf b/templates/thinkphp.conf new file mode 100644 index 0000000..47d387e --- /dev/null +++ b/templates/thinkphp.conf @@ -0,0 +1,6 @@ +location / { + if (!-e $request_filename) { + rewrite ^(.*)$ /index.php?s=$1 last; + break; + } +} diff --git a/templates/typecho.conf b/templates/typecho.conf new file mode 100644 index 0000000..890a06d --- /dev/null +++ b/templates/typecho.conf @@ -0,0 +1,5 @@ +location / { + if (!-e $request_filename) { + rewrite ^(.*)$ /index.php$1 last; + } +} diff --git a/templates/whmcs.conf b/templates/whmcs.conf new file mode 100644 index 0000000..3423145 --- /dev/null +++ b/templates/whmcs.conf @@ -0,0 +1,39 @@ +location ~ /announcements/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/announcements/$1; +} + +location ~ /download/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/download$1; +} + +location ~ /knowledgebase/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/knowledgebase/$1; +} + +location ~ /store/ssl-certificates/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/store/ssl-certificates/$1; +} + +location ~ /store/sitelock/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/store/sitelock/$1; +} + +location ~ /store/website-builder/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/store/website-builder/$1; +} + +location ~ /store/order/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/store/order/$1; +} + +location ~ /cart/domain/renew/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/cart/domain/renew$1; +} + +location ~ /account/paymentmethods/?(.*)$ { + rewrite ^/(.*)$ /index.php?rp=/account/paymentmethods$1; +} + +location ~ /admin/(addons|apps|domains|help\/license|services|setup|utilities\/system\/php-compat)(.*) { + rewrite ^/(.*)$ /admin/index.php?rp=/admin/$1$2 last; +} diff --git a/templates/wordpress.conf b/templates/wordpress.conf new file mode 100644 index 0000000..bbf67b9 --- /dev/null +++ b/templates/wordpress.conf @@ -0,0 +1,7 @@ +location / { + try_files $uri $uri/ /index.php?$args; +} +rewrite /wp-admin$ $scheme://$host$uri/ permanent; +location ~* ^/wp-content/uploads/.*\.php$ { + deny all; +} diff --git a/templates/zblog.conf b/templates/zblog.conf new file mode 100644 index 0000000..21f911d --- /dev/null +++ b/templates/zblog.conf @@ -0,0 +1,11 @@ +location / { + if (-f $request_filename/index.html){ + rewrite (.*) $1/index.html break; + } + if (-f $request_filename/index.php){ + rewrite (.*) $1/index.php; + } + if (!-f $request_filename){ + rewrite (.*) /index.php; + } +}