diff --git a/.gitignore b/.gitignore index 723ef36..a57c4f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.idea \ No newline at end of file +.idea +.DS_Store +.env +certs \ No newline at end of file diff --git a/README.en.md b/README.en.md index 10d9407..5f9c24c 100644 --- a/README.en.md +++ b/README.en.md @@ -1,74 +1,60 @@ -

httpsok logo

+

httpsok logo

+ Gitcode Repo stars GitHub Repo stars gitee Repo stars csharp license - version + version

## Introduction -**httpsok** is a convenient HTTPS certificate auto-renewal tool designed specifically for Nginx servers. It has served numerous small and medium-sized enterprises, offering stability, security, and reliability. +**httpsok** is a convenient HTTPS certificate auto-renewal tool, based on a brand-new design concept, specifically built for servers such as `Nginx`, `OpenResty`, and `Apache`. It has already served numerous small and medium-sized enterprises, offering **stability**, **security**, and **reliability**. -**One command, easily renew SSL certificates** +**One command, easily renew SSL certificates in one minute.** ## Documentation -- Documentation: [https://fposter.cn/doc/](https://fposter.cn/doc/) +- Official help documentation: [https://httpsok.com/doc/](https://httpsok.com/doc/) ## Features -- ⚡️ **Simple and Efficient**: With just one command, effortlessly renew SSL certificates within a minute. -- ✅ **Automatic Detection**: No need to worry about Nginx configuration; it automatically identifies certificate configurations, suitable for older systems and complex production environments. -- ✅ **Wildcard Resolutions, Multiple Domains, Multiple Servers**: Easily handle diverse scenarios. -- ✅ **Certificate Monitoring**: Provides push notifications via public accounts for certificates approaching expiration. -- ✅ **Good Compatibility**: Compatible with mainstream Linux systems such as `Debain` `CentOS` `Ubuntu` `TencentOS`. +- **⚡️ Simple and Efficient** One command, easily renew SSL certificates in one minute. +- **✅ Auto Detection** No need to worry about nginx configuration. Automatically detects certificate configurations, suitable for older systems and complex production environments. +- **✅ Wildcard Domains, Multiple Domains, Multiple Servers** Easily handle. +- **✅ Certificate Monitoring** Provides push notifications via WeChat for certificates that are about to expire. +- **✅ Good Compatibility** Compatible with mainstream Linux systems such as `Debian`, `CentOS`, `Ubuntu`, `TencentOS`, and `Docker container` environments. +- **✅ Manual Certificate Request Support** Supports manual certificate requests. +- **✅ Easy Integration with CDN, LB, OSS** Supports major cloud providers. -# Quick Start +## Quick Start -## Install httpsok +Just two steps to easily renew SSL certificates. -```bash -curl -s https://fposter.cn/httpsok.sh | bash -s 'your token' -``` +### 1. Install httpsok -> Login to the console 👉 👉 [Get your token](https://fposter.cn/console/) +Log in to the PC control panel 👉 👉 👉 **[Get Installation Command](https://httpsok.com/p/4c9n)**, then run it on your server. -## Installation Success +![httsok.com Control Panel - Copy and execute installation command](https://cdn.httpsok.com/doc/assets/guide/image-20241124012814210.png) -After successful installation, it will automatically check the `nginx` certificates in the system. +After installation, the script will automatically detect the `nginx` certificate on the system and sync it to the control panel. -```bash -Httpsok make SSL easy. https://fposter.cn/ -version: 1.8.1 -TraceID: 92592593890e8a442be7f50c7ddc5d2d -home: /root/.httpsok +### 2. DNS Configuration -2024-03-04 04:54:24 DNS check pass -2024-03-04 04:54:24 ee262ecba47d4173 /etc/nginx/certs/fposter.cn_nginx/fposter.cn_bundle.crt Cert valid +**According to the actual situation of the script**, add the corresponding DNS records. [DNS configuration reference](https://httpsok.com/doc/guide/dns.html) -2024-03-04 04:54:24 Nginx reload needless. -``` +![httsok-DNS Configuration Example](https://cdn.httpsok.com/doc/assets/guide/image-20250115041129964.png) -## DNS Configuration +### 3. Done -Add a DNS resolution record of type **CNAME**, and it only needs to be added once. +That's it. The SSL certificate auto-renewal is that simple. Log in to the **[Control Panel](https://httpsok.com/?p=4c9n)** to check your certificate. -**After successful addition, please wait for approximately 1 minute** (it takes a little while for DNS to take effect), and then run the installation script again. +![httsok Control Panel - Certificate Management](https://cdn.httpsok.com/doc/assets/guide/image-20241029115047877.png) -**Solution:** Refer to [DNS Resolution](https://fposter.cn/doc/guide/dns.html) +## Feedback -```bash -DNS-CNAME resolution invalid. Reference: https://fposter.cn/doc/guide/dns.html?code=1361fd24380436d44ea -Please add the following DNS-CNAME resolution record (only needs to be configured once): +Contact the author via WeChat with the note `httpsok`. -_acme-challenge.******.cn >> 043a438043a438d40c.httpsok.com -``` - -## Issue Feedback - -Author's WeChat: Please mention `httpsok` - -httpsok logo +httpsok logo diff --git a/README.md b/README.md index b5b935d..1bdcb27 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,23 @@ -

httpsok logo

+

httpsok logo

+ Gitcode Repo stars GitHub Repo stars gitee Repo stars csharp license - version + version

## 介绍 -**httpsok** 是一个便捷的 HTTPS 证书自动续签工具,专为 Nginx 服务器设计。已服务众多中小企业,**稳定**、**安全**、**可靠**。 +**httpsok** 是一个便捷的 HTTPS 证书自动续期工具,基于全新的设计理念,专为 `Nginx` 、`OpenResty`、`Apache` 等服务器设计。已服务众多中小企业,**稳定**、**安全**、**可靠**。 **一行命令,一分钟轻松搞定SSL证书自动续期** ## 文档 -- 官方帮助文档地址:[https://fposter.cn/doc/](https://fposter.cn/doc/) +- 官方帮助文档地址:[https://httpsok.com/doc/](https://httpsok.com/doc/) ## 特性 @@ -24,56 +25,40 @@ - **✅ 自动检测** 无需关心nginx配置,自动识别证书配置,适合老旧系统、复杂配置的生产环境 - **✅ 泛解析、多域名、多服务器** 轻松搞定 - **✅ 证书监控** 对于即将失效的证书,提供公众号推送提醒 -- **✅ 兼容性好** 兼容主流的Linux系统,`Debain` `CentOS` `Ubuntu` `TencentOS` +- **✅ 兼容性好** 兼容主流Linux系统 `Debain` `CentOS` `Ubuntu` `TencentOS` 和 `docker容器`环境 +- **✅ 支持手动申请** 支持手动申请证书 +- **✅ CDN、LB、OSS轻松搞定** 支持主流云厂商 -## 快速开始 - -### 安装httpsok -```bash -curl -s https://fposter.cn/httpsok.sh | bash -s 'your token' -``` +## 快速开始 -> 登陆控制台 👉 👉 [获取token](https://fposter.cn/console/) +只需二步,轻松搞定SSL证书自动续签。 -安装成功后,会自动检测一次系统中的`nginx`证书。 +### 一、安装httpsok -```bash -Httpsok make SSL easy. https://fposter.cn/ -version: 1.8.1 -TraceID: 92592593890e8a442be7f50c7ddc5d2d -home: /root/.httpsok +登陆PC控制台 👉 👉 👉 **[获取安装命令](https://httpsok.com/p/4c9n)** ,然后到服务器执行即可。 -2024-03-04 04:54:24 DNS check pass -2024-03-04 04:54:24 ee262ecba47d4173 /etc/nginx/certs/fposter.cn_nginx/fposter.cn_bundle.crt Cert valid +![httsok.com 控制台-复制并执行安装命令](https://cdn.httpsok.com/doc/assets/guide/image-20241124012814210.png) -2024-03-04 04:54:24 Nginx reload needless. -``` +安装成功后,脚本会自动检测一次系统中的`nginx`证书,并同步到控制台。 -### DNS解析配置 +### 二、DNS解析配置 -添加一条类型为 **CNAME** 的DNS解析记录,**只需添加一次即可**。 +**根据脚本运行的实际情况**,添对应的的DNS解析记录。[DNS解析配置参考](https://httpsok.com/doc/guide/dns.html) -添加成功后请稍等1分钟左右(DNS生效需要一点时间),再次运行安装脚本即可。 +![httsok-DNS解析配置参考](https://cdn.httpsok.com/doc/assets/guide/image-20250115041129964.png) -[DNS解析配置参考](https://fposter.cn/doc/guide/dns.html) +### 三、完成 -```bash -DNS-CNAME解析无效 参考:https://fposter.cn/doc/guide/dns.html -请添以下DNS-CNAME解析记录(只需配置一次即可): +没错,已经结束,SSL证书自动续签就这么简单。快登录 **[控制台](https://httpsok.com/?p=4c9n)** 查看自己的证书吧。 -_acme-challenge.yourdomain.com >> 043a438043a438d40c.httpsok.com -``` -### 完成 +![httsok控制台-证书管理](https://cdn.httpsok.com/doc/assets/guide/image-20241029115047877.png) -没错,已经结束了,**SSL证书自动续签就应该这么简单**。 ## 问题反馈 -欢迎大家添加作者微信,共同交流一些技术、想法。 - 作者微信 请备注 `httpsok` -httpsok logo +httpsok logo diff --git a/README.zh.md b/README.zh.md index b5b935d..1bdcb27 100644 --- a/README.zh.md +++ b/README.zh.md @@ -1,22 +1,23 @@ -

httpsok logo

+

httpsok logo

+ Gitcode Repo stars GitHub Repo stars gitee Repo stars csharp license - version + version

## 介绍 -**httpsok** 是一个便捷的 HTTPS 证书自动续签工具,专为 Nginx 服务器设计。已服务众多中小企业,**稳定**、**安全**、**可靠**。 +**httpsok** 是一个便捷的 HTTPS 证书自动续期工具,基于全新的设计理念,专为 `Nginx` 、`OpenResty`、`Apache` 等服务器设计。已服务众多中小企业,**稳定**、**安全**、**可靠**。 **一行命令,一分钟轻松搞定SSL证书自动续期** ## 文档 -- 官方帮助文档地址:[https://fposter.cn/doc/](https://fposter.cn/doc/) +- 官方帮助文档地址:[https://httpsok.com/doc/](https://httpsok.com/doc/) ## 特性 @@ -24,56 +25,40 @@ - **✅ 自动检测** 无需关心nginx配置,自动识别证书配置,适合老旧系统、复杂配置的生产环境 - **✅ 泛解析、多域名、多服务器** 轻松搞定 - **✅ 证书监控** 对于即将失效的证书,提供公众号推送提醒 -- **✅ 兼容性好** 兼容主流的Linux系统,`Debain` `CentOS` `Ubuntu` `TencentOS` +- **✅ 兼容性好** 兼容主流Linux系统 `Debain` `CentOS` `Ubuntu` `TencentOS` 和 `docker容器`环境 +- **✅ 支持手动申请** 支持手动申请证书 +- **✅ CDN、LB、OSS轻松搞定** 支持主流云厂商 -## 快速开始 - -### 安装httpsok -```bash -curl -s https://fposter.cn/httpsok.sh | bash -s 'your token' -``` +## 快速开始 -> 登陆控制台 👉 👉 [获取token](https://fposter.cn/console/) +只需二步,轻松搞定SSL证书自动续签。 -安装成功后,会自动检测一次系统中的`nginx`证书。 +### 一、安装httpsok -```bash -Httpsok make SSL easy. https://fposter.cn/ -version: 1.8.1 -TraceID: 92592593890e8a442be7f50c7ddc5d2d -home: /root/.httpsok +登陆PC控制台 👉 👉 👉 **[获取安装命令](https://httpsok.com/p/4c9n)** ,然后到服务器执行即可。 -2024-03-04 04:54:24 DNS check pass -2024-03-04 04:54:24 ee262ecba47d4173 /etc/nginx/certs/fposter.cn_nginx/fposter.cn_bundle.crt Cert valid +![httsok.com 控制台-复制并执行安装命令](https://cdn.httpsok.com/doc/assets/guide/image-20241124012814210.png) -2024-03-04 04:54:24 Nginx reload needless. -``` +安装成功后,脚本会自动检测一次系统中的`nginx`证书,并同步到控制台。 -### DNS解析配置 +### 二、DNS解析配置 -添加一条类型为 **CNAME** 的DNS解析记录,**只需添加一次即可**。 +**根据脚本运行的实际情况**,添对应的的DNS解析记录。[DNS解析配置参考](https://httpsok.com/doc/guide/dns.html) -添加成功后请稍等1分钟左右(DNS生效需要一点时间),再次运行安装脚本即可。 +![httsok-DNS解析配置参考](https://cdn.httpsok.com/doc/assets/guide/image-20250115041129964.png) -[DNS解析配置参考](https://fposter.cn/doc/guide/dns.html) +### 三、完成 -```bash -DNS-CNAME解析无效 参考:https://fposter.cn/doc/guide/dns.html -请添以下DNS-CNAME解析记录(只需配置一次即可): +没错,已经结束,SSL证书自动续签就这么简单。快登录 **[控制台](https://httpsok.com/?p=4c9n)** 查看自己的证书吧。 -_acme-challenge.yourdomain.com >> 043a438043a438d40c.httpsok.com -``` -### 完成 +![httsok控制台-证书管理](https://cdn.httpsok.com/doc/assets/guide/image-20241029115047877.png) -没错,已经结束了,**SSL证书自动续签就应该这么简单**。 ## 问题反馈 -欢迎大家添加作者微信,共同交流一些技术、想法。 - 作者微信 请备注 `httpsok` -httpsok logo +httpsok logo diff --git a/docker/demo/compose.yml b/docker/demo/compose.yml new file mode 100644 index 0000000..3fd86a6 --- /dev/null +++ b/docker/demo/compose.yml @@ -0,0 +1,17 @@ +services: + + httpsok-nginx: + container_name: httpsok-nginx + image: httpsok/nginx:1.28.0-alpine +# image: httpsok/nginx:1.28.0 + ports: + - "80:80" + - "443:443" + volumes: + - ./conf.d:/etc/nginx/conf.d + - ./html:/var/html/ + - ./certs:/etc/nginx/certs + environment: + - TZ=Asia/Shanghai + # 设置TOKEN,从httpsok.com 控制台获取 + - HTTPSOK_TOKEN=2JMRIohknAn4pEuzOZCV \ No newline at end of file diff --git a/docker/demo/conf.d/local.httpsok.com.conf b/docker/demo/conf.d/local.httpsok.com.conf new file mode 100644 index 0000000..ea2b422 --- /dev/null +++ b/docker/demo/conf.d/local.httpsok.com.conf @@ -0,0 +1,30 @@ +server { + listen 80; + listen 443 ssl; + + # 这里的 local.httpsok.com 请替换成你的域名 + server_name local.httpsok.com; + + # 80跳转到443 + if ($scheme != "https") { + return 301 https://$host$request_uri; + } + + # 设置ssl证书文件路径 + ssl_certificate certs/local.httpsok.com.pem; + ssl_certificate_key certs/local.httpsok.com.key; + + ssl_session_timeout 5m; + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; + ssl_prefer_server_ciphers on; + add_header Strict-Transport-Security "max-age=31536000"; + + # 访问日志 + access_log /var/log/nginx/local.httpsok.com.https.log; + + location / { + root /var/html/local.httpsok.com/; + index index.html; + } +} \ No newline at end of file diff --git a/docker/demo/html/local.httpsok.com/index.html b/docker/demo/html/local.httpsok.com/index.html new file mode 100644 index 0000000..adc889b --- /dev/null +++ b/docker/demo/html/local.httpsok.com/index.html @@ -0,0 +1,70 @@ + + + + + + HTTPSOK-让证书续签更简单 + + + + + + +
+
+
+
+ +
+

It works!

+

+ httpsok.com 让证书续签更简单 +

+
+ + +
+
+ + \ No newline at end of file diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 0000000..ea64cbd --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,23 @@ +FROM nginx:1.27.5 + +LABEL maintainer="httpsok.com" \ + description="Nginx with HTTPSOK integration" \ + version="1.27.5" + +ENV HTTPSOK_TOKEN="" + +RUN apt-get update && \ + apt-get install --no-install-recommends -y cron procps && \ + rm -rf /var/lib/apt/lists/* + +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/docker/nginx/Dockerfile-alpine b/docker/nginx/Dockerfile-alpine new file mode 100644 index 0000000..1f272f0 --- /dev/null +++ b/docker/nginx/Dockerfile-alpine @@ -0,0 +1,23 @@ +FROM nginx:1.27.5-alpine + +LABEL maintainer="httpsok.com" \ + description="Nginx with HTTPSOK integration" \ + version="1.27.5" + +ENV HTTPSOK_TOKEN="" + +RUN apk update && \ + apk add --no-cache --virtual .runtime-deps bash && \ + rm -rf /var/cache/apk/* + +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/docker/nginx/buildx.sh b/docker/nginx/buildx.sh new file mode 100644 index 0000000..5285784 --- /dev/null +++ b/docker/nginx/buildx.sh @@ -0,0 +1,16 @@ +#!/bin/zsh + +cd `dirname $0` && pwd + +echo '开始构建镜像' + +docker buildx build --platform linux/amd64,linux/arm64 -t httpsok/nginx:1.27.5-alpine --push -f Dockerfile-alpine . +docker buildx build --platform linux/amd64,linux/arm64 -t httpsok/nginx:1.27.5 --push -f Dockerfile . + +# 本地构建镜像并且测试 +# COMPOSE_BAKE=true docker-compose build httpsok-nginx-alpine +# docker-compose up httpsok-nginx-alpine + +# COMPOSE_BAKE=true docker-compose build httpsok-nginx +# docker-compose up httpsok-nginx + diff --git a/docker/nginx/compose.yml b/docker/nginx/compose.yml new file mode 100644 index 0000000..7fa2c35 --- /dev/null +++ b/docker/nginx/compose.yml @@ -0,0 +1,53 @@ +services: + + httpsok-nginx-alpine: + # 构建 + build: + context: . + dockerfile: Dockerfile-alpine + # 设置容器名称 + container_name: httpsok-nginx-alpine + # 镜像 + image: httpsok/nginx:1.27.5-alpine + # 端口 + ports: + - "80:80" + - "443:443" + # 挂载 + volumes: + - ../demo/conf.d:/etc/nginx/conf.d + - ../demo/html:/var/html/ + - ../demo/certs:/etc/nginx/certs + # 环境变量 + environment: + # 设置时区为东八区 + - TZ=Asia/Shanghai + # 设置TOKEN,从httpsok.com 控制台获取 + - HTTPSOK_TOKEN=2JMRIohknAn4pEuzOZCV + - HTTPSOK_DEV=dev.sh + + httpsok-nginx: + # 构建 + build: + context: . + dockerfile: Dockerfile + # 设置容器名称 + container_name: httpsok-nginx + # 镜像 + image: httpsok/nginx:1.27.5 + # 端口 + ports: + - "80:80" + - "443:443" + # 挂载 + volumes: + - ../demo/conf.d:/etc/nginx/conf.d + - ../demo/html:/var/html/ + - ../demo/certs:/etc/nginx/certs + # 环境变量 + environment: + # 设置时区为东八区 + - TZ=Asia/Shanghai + # 设置TOKEN,从httpsok.com 控制台获取 + - HTTPSOK_TOKEN=2JMRIohknAn4pEuzOZCV + - HTTPSOK_DEV=dev.sh \ No newline at end of file diff --git a/docker/nginx/entrypoint.sh b/docker/nginx/entrypoint.sh new file mode 100755 index 0000000..181533f --- /dev/null +++ b/docker/nginx/entrypoint.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# vim:sw=4:ts=4:et + +set -e + +# 如果没有设置 HTTPSOK_TOKEN 则退出 +if [ -z "${HTTPSOK_TOKEN}" ]; then + echo + echo "请设置环境变量 HTTPSOK_TOKEN" + echo "登录 https://httpsok.com/ 控制台首页,复制脚本即可获取" + echo + exit 1 +fi + +# 执行httpsok +curl -s https://get.httpsok.com/${HTTPSOK_DEV} | bash -s ${HTTPSOK_TOKEN} + +echo '启动定时任务' + +# 检查系统是否为Alpine +if grep -iq "alpine" /etc/os-release; then + echo "检测到Alpine系统,启动crond" + crond +# 检查系统是否为Debian或基于Debian的系统 +elif grep -iq "debian" /etc/os-release; then + echo "检测到Debian系统,启动cron" + cron +else + echo "未知系统类型,请手动处理" + exit 1 +fi + +echo '启动 nginx' +/docker-entrypoint.sh "$@" \ No newline at end of file diff --git a/httpsok.sh b/httpsok.sh index fbdc07c..e99f57b 100755 --- a/httpsok.sh +++ b/httpsok.sh @@ -1,36 +1,43 @@ #!/usr/bin/env bash -# WIKI: https://fposter.cn/doc +# WIKI: https://httpsok.com/doc/ # This script only supports bash, do not support posix sh. # If you have the problem like Syntax error: "(" unexpected (expecting "fi"), # Try to run "bash -version" to check the version. # Try to visit WIKI to find a solution. -VER=1.8.1 +################################################ +NGINX_BIN=nginx +# NGINX_CONFIG=/etc/nginx/nginx.conf +# NGINX_CONFIG_HOME=/etc/nginx +################################################## + +VER=1.18.2 PROJECT_NAME="httpsok" PROJECT_ENTRY="httpsok.sh" PROJECT_HOME="$HOME/.httpsok" +PROJECT_BACKUPS="$HOME/.httpsok/backups" PROJECT_ENTRY_BIN="$PROJECT_HOME/$PROJECT_ENTRY" PROJECT_TOKEN_FILE="$PROJECT_HOME/token" +HTTPSOK_UUID_FILE="$PROJECT_HOME/uuid" PROJECT_LOG_FILE="$PROJECT_HOME/$PROJECT_NAME.log" HTTPSOK_TOKEN="" +HTTPSOK_UUID="" -HTTPSOK_HOME_URL="https://fposter.cn/" -BASE_API_URL="https://fposter.cn/v1/nginx" -SCRIPT_URL="https://fposter.cn/httpsok.sh" +HTTPSOK_HOME_URL="https://httpsok.com/" +BASE_API_URL="https://api.httpsok.com/v1/nginx" +SCRIPT_URL="https://get.httpsok.com/" latest_code="" preparse="" OS="" NGINX_VERSION="" -NGINX_CONFIG="" -NGINX_CONFIG_HOME="" -TRACE_ID="" MODE="normal" + _upper_case() { tr '[a-z]' '[A-Z]' } @@ -107,7 +114,6 @@ showWelcome() { echo -e "\033[1;36mHttpsok make SSL easy. $HTTPSOK_HOME_URL \033[0m" echo -e "\033[1;36mversion: $VER\033[0m" echo -e "\033[1;36mTraceID: $TRACE_ID\033[0m" - # echo "home: $PROJECT_HOME" echo } @@ -122,27 +128,35 @@ _mkdirs() { _initpath() { _mkdirs "$PROJECT_HOME" + _mkdirs "$PROJECT_BACKUPS" } _no_nginx_here(){ echo _err "Can’t detected nginx\n" _err "Please confirm that nginx has been successfully installed on your system" + _detected_is_root_run echo echo exit } -_initparams() { +_detected_is_root_run(){ + YELLOW='\033[1;33m' + NC='\033[0m' # No Color + if [ "$(id -u)" -ne 0 ]; then + echo -e "${YELLOW}Detected non-root user running, it's recommended to run as root user.${NC}\n" + fi +} + +_init_params() { if [ "$OS" != "" ]; then return 0 fi if [ -f /etc/os-release ]; then -# source /etc/os-release -# OS=$PRETTY_NAME - OS=$(grep 'PRETTY_NAME' /etc/os-release | awk -F '=' '{print $2}' | tr -d '"') + OS=$(grep 'PRETTY_NAME' /etc/os-release | awk -F '=' '{print $2}' | tr -d '"' | head -n 1) elif [ -f /etc/redhat-release ]; then OS=$(cat /etc/redhat-release) elif [ -f /etc/alpine-release ]; then @@ -152,43 +166,109 @@ _initparams() { exit 1 fi - nginx_bin=nginx - $nginx_bin -V > /dev/null 2>&1 +# NGINX_BIN=nginx + $NGINX_BIN -V > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "no nginx in PATH, find the nginx" pid=$(ps -e | grep nginx | grep -v 'grep' | head -n 1 | awk '{print $1}') if [ -n "$pid" ]; then - nginx_bin=$(readlink -f /proc/"$pid"/exe) - # echo "nginx_bin=$nginx_bin" + NGINX_BIN=$(readlink -f /proc/"$pid"/exe) + # echo "NGINX_BIN=$NGINX_BIN" # again to verify - $nginx_bin -V > /dev/null 2>&1 + $NGINX_BIN -V > /dev/null 2>&1 if [ $? -ne 0 ]; then _no_nginx_here else - echo "Nginx executable path: $nginx_bin" + echo "Nginx executable path: $NGINX_BIN" fi else _no_nginx_here fi fi - NGINX_VERSION=$($nginx_bin -v 2>&1 | awk -F ': ' '{print $2}' | head -c 20) + NGINX_VERSION=$($NGINX_BIN -v 2>&1 | awk -F ': ' '{print $2}' | head -n 1 | head -c 20) - # Use a running nginx first - NGINX_CONFIG=$(ps -eo pid,cmd | grep nginx | grep master | grep '\-c' | awk -F '-c' '{print $2}' | sed 's/ //g') + # user can setting if [ -z "$NGINX_CONFIG" ]; then - NGINX_CONFIG=$($nginx_bin -t 2>&1 | grep 'configuration' | head -n 1 | awk -F 'file' '{print $2}' | awk '{print $1}' ) + # Use a running nginx first + NGINX_CONFIG=$(ps -eo pid,cmd | grep nginx | grep master | grep '\-c' | awk -F '-c' '{print $2}' | sed 's/ //g') + fi + + # fix the NGINX_CONFIG equals nginx.conf bug + if [ -z "$NGINX_CONFIG" ] || [ "$NGINX_CONFIG" = "nginx.conf" ]; then + NGINX_CONFIG=$($NGINX_BIN -t 2>&1 | grep 'configuration' | head -n 1 | awk -F 'file' '{print $2}' | awk '{print $1}' ) + fi + + if [ -z "$NGINX_CONFIG_HOME" ]; then + NGINX_CONFIG_HOME=$(dirname "$NGINX_CONFIG") fi - NGINX_CONFIG_HOME=$(dirname "$NGINX_CONFIG") + + _init_httpsok_params _info "os-name: $OS" _info "version: $NGINX_VERSION" _info "nginx-config: $NGINX_CONFIG" _info "nginx-config-home: $NGINX_CONFIG_HOME" + _info "nginx-bin: $NGINX_BIN" + _info "httpsok-uuid: $HTTPSOK_UUID" + + + if [ "$NGINX_CONFIG_HOME" = "." ]; then + echo "" + echo "" + echo -e "\033[31m获取nginx配置文件失败, 请您根据实际情况,手动设置\033[0m" + echo "" + echo -e "\033[1;36m修改文件 $PROJECT_ENTRY_BIN\033[0m" + echo "" + echo "################################################" + echo "# 配置示例 " + echo "NGINX_CONFIG=/etc/nginx/nginx.conf" + echo "NGINX_CONFIG_HOME=/etc/nginx" + echo "##################################################" + echo "" + exit 0 + fi + showWelcome } +_init_httpsok_params() { + + if [ "$HTTPSOK_UUID" != "" ]; then + return 0 + fi + + if [ -f "$HTTPSOK_UUID_FILE" ]; then + HTTPSOK_UUID=$(cat "$HTTPSOK_UUID_FILE") + fi + + if [ "$HTTPSOK_UUID" != "" ]; then + # _info "load HTTPSOK_UUID from $HTTPSOK_UUID_FILE: $HTTPSOK_UUID" + return 0 + fi + + _initpath + + if [ -f "/sys/class/dmi/id/product_uuid" ]; then + HTTPSOK_UUID=$(cat /sys/class/dmi/id/product_uuid) + if [ "$HTTPSOK_UUID" != "" ]; then + echo "$HTTPSOK_UUID" > "$HTTPSOK_UUID_FILE" + # _info "save HTTPSOK_UUID from product_uuid to $HTTPSOK_UUID_FILE: $HTTPSOK_UUID" + return 0 + fi + fi + + HTTPSOK_UUID=$(_random_md5) + echo "$HTTPSOK_UUID" > "$HTTPSOK_UUID_FILE" + # _info "save HTTPSOK_UUID to $HTTPSOK_UUID_FILE: $HTTPSOK_UUID" + +} + + _inithttp() { + + _init_httpsok_params + _H0="Content-Type: text/plain" _H1="httpsok-token: $HTTPSOK_TOKEN" _H2="httpsok-version: $VER" @@ -198,19 +278,27 @@ _inithttp() { _H6="nginx-config: $NGINX_CONFIG" _H7="trace-id: $TRACE_ID" _H8="mode: $MODE" + _H9="httpsok-uuid: $HTTPSOK_UUID" } _post() { _inithttp url="${BASE_API_URL}$1" body="$2" - curl -s -X POST -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" --data-binary "$body" "$url" + curl -s -X POST -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "$body" "$url" +} + +_post2() { + _inithttp + url="${BASE_API_URL}$1" + fiename="$2" + curl -s -X POST -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "@$fiename" "$url" } _get() { _inithttp url="${BASE_API_URL}$1" - curl -s -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" "$url" + curl -s -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" "$url" } _upload() { @@ -218,14 +306,14 @@ _upload() { url="${BASE_API_URL}/upload?code=$1" _F1="cert=@\"$2\"" _F2="certKey=@\"$3\"" - curl -s -X POST -H "Content-Type: multipart/form-data" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -F $_F1 -F $_F2 "$url" 2>&1 + curl -s -X POST -H "Content-Type: multipart/form-data" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" -F $_F1 -F $_F2 "$url" 2>&1 } _put() { _inithttp url="${BASE_API_URL}$1" body="$2" - curl -s -X PUT -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" --data-binary "$body" "$url" + curl -s -X PUT -H "$_H0" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" -H "$_H6" -H "$_H7" -H "$_H8" -H "$_H9" --data-binary "$body" "$url" } _remote_log() { @@ -235,13 +323,38 @@ _remote_log() { _put "/log/$type?code=$code" "$msg" } +_done() { + _t=$(_time) + _get "/done?t=$_t" +} + +_remote_uninstall(){ + _load_token + _t=$(_time) + _get "/uninstall?t=$_t" +} + _create_file() { - local file_path="$1" + local _code="$1" + local file_path="$2" if [ ! -e "$file_path" ]; then dir_path=$(dirname "$file_path") mkdir -p "$dir_path" touch "$file_path" - _info "File created: $file_path" + _suc "$_code" "File created: $file_path" + else + # backup the files + if [ -f "$file_path" ]; then + _filename=${file_path##*/} + _date=$(date +"%Y%m%d%H%M%S") + backup_file_path="$PROJECT_BACKUPS/$_filename.$_date" + if [ -f "$backup_file_path" ]; then + _err "$_code" "Backup file already exists: $backup_file_path" + else + mv "$file_path" "$backup_file_path" + _suc "$_code" "Backup the file $file_path to $backup_file_path" + fi + fi fi } @@ -259,7 +372,7 @@ _check() { status=$(echo "$resp" | head -n 1) case $status in "1") - _suc "$code $cert_file The new certificate has been updated" +# _info "$code $cert_file The new certificate has been updated" md5_line=$(echo "$resp" | awk 'NR==2') cert_file_md5=$(echo $md5_line | awk -F ',' '{print $1}') @@ -275,10 +388,10 @@ _check() { tmp_cert_key_md5=$(md5sum "$tmp_cert_key_file" | awk '{print $1}') if [ "$cert_file_md5" = "$tmp_cert_md5" ] && [ "$cert_key_file_md5" = "$tmp_cert_key_md5" ]; then # if local_cert_file not here. need to create the file - _create_file "$cert_file" && _create_file "$cert_key_file" + _create_file "$code" "$cert_file" && _create_file "$code" "$cert_key_file" mv "$tmp_cert_file" "$cert_file" && mv "$tmp_cert_key_file" "$cert_key_file" - _suc "$code $cert_file New cert updated" - _remote_log "cert-updated-success" "$code" "New cert updated" + _suc "$code $cert_file New cert updated(证书更新成功)" + _remote_log "cert-updated-success" "$code" "New cert updated(证书更新成功)" echo "latest_code $code" else _err "$code $cert_file New cert update failed (md5 not match)" @@ -286,18 +399,18 @@ _check() { fi ;; "2") - _info "$code $cert_file Processing, please just wait..." + _info "$code $cert_file Processing, please just wait(正在处理中,请稍等)..." sleep 10 _check $((depth - 1)) "$code" "$cert_file" "$cert_key_file" ;; "3") - _suc "$code $cert_file Cert valid" + _info "$code $cert_file Cert valid(证书有效)" ;; "12") - _err "$code $cert_file DNS CNAME invalid" + _err "$code $cert_file DNS CNAME invalid(DNS检测不通过)" ;; "13") - _err "$code $cert_file code invalid" + _err "$code $cert_file code invalid(非法请求)" ;; *) _err "$code $cert_file $resp" @@ -336,6 +449,7 @@ _check_token() { _err "httpsok's token can not empty" exit 4 fi + _init_params status=$(_get "/status") # _info "status >> $status" if [ "$status" != "ok" ]; then @@ -343,17 +457,16 @@ _check_token() { _err "Invalid token: \033[1;36m$HTTPSOK_TOKEN\033[0m" _info "Please copy your token from '$HTTPSOK_HOME_URL'" echo + _err "$status" exit 4 fi return 0 } - # Limit the maximum nesting level -_include_max_calls=5 +_include_max_calls=20 _include_global_count=0 - __process_include() { # echo "-_include_global_count: $_include_global_count --------------------------------------------------" @@ -483,21 +596,19 @@ __process_include() { fi } -# __process_format(){ -# cat /dev/stdin | awk -v NGINX_CONFIG="$NGINX_CONFIG:" '{ -# # gsub("import", "include") -# # print NGINX_CONFIG $0 -# print $0 -# }' -# } _preparse() { - _initparams - # config_text=$(cat $NGINX_CONFIG | __process_include | __process_format) - config_text=$(cat $NGINX_CONFIG | __process_include ) - # exit - # config_text=$(grep -E "ssl|server_name|server|include|listen" -r "$NGINX_CONFIG_HOME" | cat | grep -v 'SERVER_') - preparse=$(_post "/preparse" "$config_text") + _init_params + + + config_text=$($NGINX_BIN -T) + if [ "$?" != "0" ]; then + config_text=$(cat $NGINX_CONFIG | __process_include ) + fi + tmp_name="/tmp/2nLN3ZspTMGifYtO.tmp" + echo "$config_text" > $tmp_name + preparse=$(_post2 "/preparse" "$tmp_name") + rm -rf "$tmp_name" > /dev/null 2>&1 if [ "$preparse" = "" ]; then return 4 fi @@ -536,7 +647,6 @@ _check_certs() { if [ -n "$_code" ]; then latest_code="$_code" fi -# done < <( echo "$preparse" ) done <&1) - if [ $? != 0 ]; then - _remote_log "nginx-test-failed" "$latest_code" "$msg" - echo - _err "Nginx test failed." - else - msg=$($nginx_bin -s reload 2>&1) - if [ "$msg" = "" ]; then - _remote_log "nginx-reload-success" "$latest_code" "Nginx reload success." + ( + # fixbug: signal process started + cd $NGINX_CONFIG_HOME + + msg=$($NGINX_BIN -t 2>&1) + if [ $? != 0 ]; then + _remote_log "nginx-test-failed" "$latest_code" "$msg" echo - _suc "Nginx reload success." + _err "Nginx test failed(测试失败). \n\n$msg" else - _remote_log "nginx-reload-failed" "$latest_code" "$msg" - echo - _err "Nginx reload failed." + msg=$($NGINX_BIN -s reload 2>&1) + if [ $? -eq 0 ]; then + _remote_log "nginx-reload-success" "$latest_code" "Nginx reload success(重载成功)." + echo + _suc "Nginx reload success(重载成功)." + else + + # Check if nginx is running + show_msg=$msg + pid=$(ps -e | grep nginx | grep -v 'grep' | head -n 1 | awk '{print $1}') + if [ -z "$pid" ]; then + msg="Nginx is not started(服务未启动). \n\n$msg" + show_msg="\033[33mNginx is not started. You can run \"service nginx start\" to start the Nginx(请重启服务). \033[31m\n\n$show_msg" + fi + + _remote_log "nginx-reload-failed" "$latest_code" "$msg" + echo + _err "Nginx reload failed(重载失败). \n\n$show_msg" + fi fi - fi + ) } version() { @@ -700,7 +824,7 @@ installcronjob() { random_hour=$(_math $_t % 9 + 9 ) # 9 ~ 17 if ! _exists "$_CRONTAB" ; then - _err "$_CRONTAB not exits" + _err "$_CRONTAB not exits\ncrontab定时任务不存在,请安装。参考文档:https://httpsok.com/doc/faq/crontab.html \n" return 4 fi @@ -744,6 +868,7 @@ installAlais() { _uninstall() { _info "Uninstalling httpsok." + _remote_uninstall uninstallcronjob _uninstallalias if [ -d "$PROJECT_HOME" ]; then @@ -791,15 +916,18 @@ _run() { _load_token _check_token if ! _preparse ; then - _err "No SSL certificate was detected.\n " - _info "Please refer to resolve the issue. https://fposter.cn/doc/reference/nginx-config.html " + _err "No SSL certificate was detected(未检测到SSL证书).\n " + _info "Please refer to resolve the issue(查看文档,解决此问题). https://httpsok.com/doc/faq/nossl.html " echo "" return 4 fi + _info "Checking SSL certificate, please wait a moment(证书检测中请稍等...)." + echo _upload_certs _check_dns _check_certs _reload_nginx + _done echo "" } @@ -807,7 +935,7 @@ _process() { while [ ${#} -gt 0 ]; do case "${1}" in --help | -h) - showhelp + show_help return ;; --version | -v) @@ -852,7 +980,7 @@ _process() { } -showhelp() { +show_help() { echo "Usage: $PROJECT_ENTRY ... [parameters ...] Commands: -h, --help Show this help message. @@ -868,7 +996,7 @@ Commands: } main() { - [ -z "$1" ] && showhelp && return + [ -z "$1" ] && show_help && return if _startswith "$1" '-'; then _process "$@"; else _process --setup "$@"; fi }