diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml index a8f525880..01c152fc9 100644 --- a/.github/workflows/translate.yml +++ b/.github/workflows/translate.yml @@ -1,17 +1,13 @@ - name: Weekly Translation Workflow on: schedule: - # 每周日 UTC 02:00 执行 (北京时间周日 10:00) - cron: '0 2 * * 0' - workflow_dispatch: # 允许手动触发 - + workflow_dispatch: permissions: contents: write - jobs: translate: runs-on: ubuntu-latest @@ -50,148 +46,115 @@ jobs: return bool(re.search(r'[\u4e00-\u9fff]', text)) def translate_text(text, target_lang): + if not text.strip() or not is_chinese(text): + return text try: - return GoogleTranslator(source='zh-CN', target=target_lang).translate(text) + # 过滤掉一些不该翻译的特殊符号 + clean_text = text.strip() + result = GoogleTranslator(source='zh-CN', target=target_lang).translate(clean_text) + return result except Exception as e: - print(f"\nTranslation error: {e}") + print(f"\n[Error] {e}") return text - - def translate_line_preserving_variables(line, target_lang): + + def process_content_with_vars(content, target_lang): """ - Translate only Chinese parts in echo/read/send_stats commands, excluding shell variables + 核心逻辑:保护 ${var} 和 $var,翻译其中的中文部分 """ - # Match double or single quoted strings - def repl(match): - full_string = match.group(0) - quote = full_string[0] - content = full_string[1:-1] - # Split by variable expressions - parts = re.split(r'(\$\{?\w+\}?)', content) - translated_parts = [ - translate_text(p, target_lang) if is_chinese(p) else p - for p in parts - ] - return quote + ''.join(translated_parts) + quote - - return re.sub(r'(?:\'[^\']*\'|"[^"]*")', repl, line) + # 匹配 ${var} 或 $var (字母数字下划线) + parts = re.split(r'(\$\{\w+\}|\$\w+)', content) + translated_parts = [] + for p in parts: + if p.startswith('$'): # 变量部分,保持原样 + translated_parts.append(p) + elif is_chinese(p): # 中文部分,翻译 + translated_parts.append(translate_text(p, target_lang)) + else: # 其他英文/符号,保持原样 + translated_parts.append(p) + return "".join(translated_parts) + + def universal_translator(line, target_lang): + """ + 通用翻译引擎:识别行内所有引号内容并翻译 + """ + # 1. 保护注释行 + leading_space = re.match(r'^(\s*)', line).group(1) + stripped = line.strip() + if stripped.startswith('#'): + comment_content = stripped[1:].strip() + if is_chinese(comment_content): + return f"{leading_space}# {translate_text(comment_content, target_lang)}\n" + return line + + # 2. 识别所有引号内的内容 (双引号或单引号) + # 使用正则匹配引号对,同时处理转义引号 \" + def replacer(match): + quote_type = match.group(1) # ' 或 " + content = match.group(2) # 引号内的文本内容 + if is_chinese(content): + # 翻译内容,但保护里面的变量 + translated = process_content_with_vars(content, target_lang) + return f"{quote_type}{translated}{quote_type}" + return match.group(0) + + # 匹配 "content" 或 'content' + new_line = re.sub(r'([\'"])(.*?)(? Google翻译语言代码 - languages = { - 'en': 'en', # 英语 - 'tw': 'zh-TW', # 繁体中文 - 'kr': 'ko', # 韩语 - 'jp': 'ja' # 日语 - } - - success_count = 0 - - for dir_name, lang_code in languages.items(): - output_file = f'{dir_name}/kejilion.sh' - if translate_file(input_file, output_file, lang_code): - success_count += 1 - print(f"✓ Successfully translated to {dir_name}") - else: - print(f"✗ Failed to translate to {dir_name}") - print("-" * 50) - - print(f"\nTranslation summary: {success_count}/{len(languages)} languages completed") - - if success_count == 0: - sys.exit(1) + langs = {'en': 'en', 'tw': 'zh-TW', 'kr': 'ko', 'jp': 'ja'} + for dir_name, lang_code in langs.items(): + translate_file(input_file, f'{dir_name}/kejilion.sh', lang_code) EOF - name: Run translation - run: | - python translate.py + run: python translate.py - name: Check for changes id: check_changes run: | git add . - if git diff --staged --quiet; then - echo "has_changes=false" >> $GITHUB_OUTPUT - else - echo "has_changes=true" >> $GITHUB_OUTPUT - fi + git diff --staged --quiet || echo "has_changes=true" >> $GITHUB_OUTPUT - name: Commit and push changes if: steps.check_changes.outputs.has_changes == 'true' run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - git add . git commit -m "🌐 Weekly translation update - $(date +'%Y-%m-%d %H:%M:%S')" git push env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + - name: Create summary if: always() run: | echo "## Translation Summary 📊" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Language | Directory | Status |" >> $GITHUB_STEP_SUMMARY - echo "|----------|-----------|--------|" >> $GITHUB_STEP_SUMMARY - + echo "| Language | Status |" >> $GITHUB_STEP_SUMMARY + echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY for dir in en tw kr jp; do - if [ -f "$dir/kejilion.sh" ]; then - size=$(stat -c%s "$dir/kejilion.sh") - echo "| $dir | /$dir/ | ✅ Success (${size} bytes) |" >> $GITHUB_STEP_SUMMARY - else - echo "| $dir | /$dir/ | ❌ Failed |" >> $GITHUB_STEP_SUMMARY - fi + [ -f "$dir/kejilion.sh" ] && status="✅ Success" || status="❌ Failed" + echo "| $dir | $status |" >> $GITHUB_STEP_SUMMARY done - - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Execution time:** $(date)" >> $GITHUB_STEP_SUMMARY - - if [ "${{ steps.check_changes.outputs.has_changes }}" == "true" ]; then - echo "**Changes:** New translations committed and pushed" >> $GITHUB_STEP_SUMMARY - else - echo "**Changes:** No changes detected" >> $GITHUB_STEP_SUMMARY - fi - - diff --git a/apps/README.md b/apps/README.md new file mode 100644 index 000000000..e238e5132 --- /dev/null +++ b/apps/README.md @@ -0,0 +1,4 @@ +# 🚀 开发者应用入驻指南 (kejilion.sh) + +https://github.com/kejilion/apps + diff --git a/auto_cert_renewal.sh b/auto_cert_renewal.sh index 4d574d6dc..baf58087f 100644 --- a/auto_cert_renewal.sh +++ b/auto_cert_renewal.sh @@ -23,35 +23,78 @@ for cert_file in $certs_directory*_cert.pem; do # 计算距离过期还有几天 days_until_expiry=$(( ($expiration_timestamp - $current_timestamp) / 86400 )) - # 检查是否需要续签(在满足续签条件的情况下) if [ $days_until_expiry -le $days_before_expiry ]; then + echo "证书将在${days_before_expiry}天内过期,正在进行自动续签。" - - docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n - docker stop nginx > /dev/null 2>&1 + # 1. 检查目录是否存在 + docker exec nginx [ -d /var/www/letsencrypt ] && DIR_OK=true || DIR_OK=false + + # 2. 检查配置文件是否包含关键字 + # 假设你的配置文件在容器内的 /etc/nginx/conf.d/ 目录下(这是 Nginx 容器的默认路径) + docker exec nginx grep -q "letsencrypt" /etc/nginx/conf.d/$yuming.conf && CONF_OK=true || CONF_OK=false + + # 输出结果 + echo "--- 自动化环境检测报告 ---" + if [ "$DIR_OK" = true ]; then echo "✅ 目录检测:/var/www/letsencrypt 存在"; else echo "❌ 目录检测:/var/www/letsencrypt 不存在"; fi + if [ "$CONF_OK" = true ]; then echo "✅ 配置检测:$yuming.conf 已包含续签规则"; else echo "❌ 配置检测:$yuming.conf 未发现 letsencrypt 字样"; fi + + if [ "$DIR_OK" = true ] && [ "$CONF_OK" = true ]; then + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n + + docker run --rm \ + -v "/etc/letsencrypt:/etc/letsencrypt" \ + -v "/home/web/letsencrypt:/var/www/letsencrypt" \ + certbot/certbot certonly \ + --webroot \ + -w /var/www/letsencrypt \ + -d "$yuming" \ + --email your@email.com \ + --agree-tos \ + --no-eff-email \ + --key-type ecdsa \ + --force-renewal + + mkdir -p /home/web/certs/ + cp /etc/letsencrypt/live/$yuming/fullchain.pem /home/web/certs/${yuming}_cert.pem > /dev/null 2>&1 + cp /etc/letsencrypt/live/$yuming/privkey.pem /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 + + openssl rand -out /home/web/certs/ticket12.key 48 + openssl rand -out /home/web/certs/ticket13.key 80 + + docker exec nginx nginx -t && docker exec nginx nginx -s reload + + else + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n + + docker stop nginx > /dev/null 2>&1 + + # if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + # iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + # fi + + # iptables -P INPUT ACCEPT + # iptables -P FORWARD ACCEPT + # iptables -P OUTPUT ACCEPT + # iptables -F - iptables -P INPUT ACCEPT - iptables -P FORWARD ACCEPT - iptables -P OUTPUT ACCEPT - iptables -F + # ip6tables -P INPUT ACCEPT + # ip6tables -P FORWARD ACCEPT + # ip6tables -P OUTPUT ACCEPT + # ip6tables -F - ip6tables -P INPUT ACCEPT - ip6tables -P FORWARD ACCEPT - ip6tables -P OUTPUT ACCEPT - ip6tables -F + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d $yuming --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa - docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d $yuming --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + mkdir -p /home/web/certs/ + cp /etc/letsencrypt/live/$yuming/fullchain.pem /home/web/certs/${yuming}_cert.pem > /dev/null 2>&1 + cp /etc/letsencrypt/live/$yuming/privkey.pem /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 - mkdir -p /home/web/certs/ - cp /etc/letsencrypt/live/$yuming/fullchain.pem /home/web/certs/${yuming}_cert.pem > /dev/null 2>&1 - cp /etc/letsencrypt/live/$yuming/privkey.pem /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 + openssl rand -out /home/web/certs/ticket12.key 48 + openssl rand -out /home/web/certs/ticket13.key 80 - openssl rand -out /home/web/certs/ticket12.key 48 - openssl rand -out /home/web/certs/ticket13.key 80 - - docker start nginx > /dev/null 2>&1 + docker start nginx > /dev/null 2>&1 + fi echo "证书已成功续签。" else diff --git a/cn/kejilion.sh b/cn/kejilion.sh index 1c2b0d9c1..38aabe80a 100644 --- a/cn/kejilion.sh +++ b/cn/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.5" +sh_v="4.3.2" gl_hui='\e[37m' @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -213,12 +213,15 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then echo -e "${gl_huang}提示: ${gl_bai}磁盘空间不足!" echo "当前可用空间: $((available_space_mb/1024))G" echo "最小需求空间: ${required_gb}G" @@ -230,8 +233,15 @@ check_disk_space() { } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,18 +417,31 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } @@ -426,61 +449,8 @@ install_add_docker_cn install_add_docker() { echo -e "${gl_huang}正在安装docker环境...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -1025,91 +995,84 @@ disable_ddos_defense() { # 管理国家IP规则的函数 manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # 如果 ipset 不存在则创建 - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # 下载 IP 区域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "错误:下载 $country_code 的 IP 区域文件失败" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 将 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "错误:下载 $country_code 的 IP 区域文件失败" + continue + fi - # 使用 iptables 阻止 IP - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "已成功阻止 $country_code 的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # 为允许的国家创建 ipset(如果不存在) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "已成功阻止 $country_code 的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 下载 IP 区域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "错误:下载 $country_code 的 IP 区域文件失败" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 删除现有的国家规则 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "错误:下载 $country_code 的 IP 区域文件失败" + continue + fi - # 将 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # 仅允许指定国家的 IP - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "已成功仅允许 $country_code 的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # 删除国家的 iptables 规则 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "已成功允许 $country_code 的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 销毁 ipset - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "已成功解除 $country_code 的 IP 地址限制" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "已成功解除 $country_code 的 IP 地址限制" + ;; + + *) + echo "用法: manage_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables @@ -1223,18 +1186,18 @@ iptables_panel() { ;; 15) - read -e -p "请输入阻止的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入阻止的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules block $country_code send_stats "允许国家 $country_code 的IP" ;; 16) - read -e -p "请输入允许的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入允许的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules allow $country_code send_stats "阻止国家 $country_code 的IP" ;; 17) - read -e -p "请输入清除的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入清除的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules unblock $country_code send_stats "清除国家 $country_code 的IP" ;; @@ -1252,8 +1215,6 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 @@ -1342,11 +1303,9 @@ ldnmp_v() { install_ldnmp_conf() { # 创建必要的目录和文件 - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx web/letsencrypt && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "letsencrypt" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # 获取国家代码(如 CN、US 等) + local country=$(curl -s ipinfo.io/country) + + # 根据国家设置 DNS + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "已切换为 IPv4 优先" +send_stats "已切换为 IPv4 优先" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,8 +1392,16 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # mysql调优 + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear echo "LDNMP环境安装完毕" @@ -1428,7 +1433,7 @@ install_ssltls() { local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1443,11 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1475,7 +1484,7 @@ if [ -z "$yuming" ]; then fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1534,12 +1543,77 @@ certs_status() { echo -e "4. 防火墙限制 ➠ 检查80/443端口是否开放,确保验证可访问" echo -e "5. 申请次数超限 ➠ Let's Encrypt有每周限额(5次/域名/周)" echo -e "6. 国内备案限制 ➠ 中国大陆环境请确认域名是否备案" - break_end - clear - echo "请再次尝试部署 $webname" - add_yuming - install_ssltls - certs_status + echo "------------------------" + echo "1. 重新申请 2. 导入已有证书 3. 不带证书改用HTTP访问 0. 退出" + echo "------------------------" + read -e -p "请输入你的选择: " sub_choice + case $sub_choice in + 1) + send_stats "重新申请" + echo "请再次尝试部署 $webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "导入已有证书" + + # 定义文件路径 + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. 输入证书 (ECC 和 RSA 证书开头都是 BEGIN CERTIFICATE) + echo "请粘贴 证书 (CRT/PEM) 内容 (按两次回车结束):" + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. 输入私钥 (兼容 RSA, ECC, PKCS#8) + echo "请粘贴 证书私钥 (Private Key) 内容 (按两次回车结束):" + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. 智能校验 + # 只要包含 "BEGIN CERTIFICATE" 和 "PRIVATE KEY" 即可通过 + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # 识别当前证书类型并显示 + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "检测到 ECC 证书已成功保存。" + else + echo "检测到 RSA 证书已成功保存。" + fi + auth_method="ssl_imported" + else + echo "错误:无效的证书或私钥格式!" + certs_status + fi + + ;; + 3) + send_stats "不带证书改用HTTP访问" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "退出申请" + exit + ;; + esac fi } @@ -1561,6 +1635,40 @@ add_yuming() { } +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "请输入访问/监听端口,回车默认使用 80: " access_port + access_port=${access_port:-80} + fi +} + + + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # 如果 access_port 为空,则跳过 + [ -z "$access_port" ] && return 0 + + # 删除所有 listen 行 + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # 在 server { 后插入新的 listen + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1679,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1688,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1635,7 +1724,7 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address @@ -1694,7 +1783,6 @@ web_cache() { send_stats "清理站点缓存" cf_purge_cache cd /home/web && docker compose restart - restart_redis } @@ -1776,7 +1864,7 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then CFmessage=" cf模式已开启" else CFmessage="" @@ -1847,6 +1935,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # 删除旧定义 + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # 生成插入内容 + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # 插入到 “Happy publishing” 之前 + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1990,19 +2115,11 @@ nginx_gzip() { web_security() { send_stats "LDNMP环境防御" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "服务器网站防御程序 ${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "服务器网站防御程序 ${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" echo "1. 安装防御程序" echo "------------------------" @@ -2024,11 +2141,16 @@ web_security() { case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,56 +2164,57 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null echo "Fail2Ban防御程序已卸载" + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) @@ -2104,14 +2227,14 @@ web_security() { wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status echo "已配置cloudflare模式,可在cf后台,站点-安全性-事件中查看拦截记录" @@ -2176,26 +2299,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { - -CONFIG_FILE="/home/web/nginx.conf" +check_ldnmp_mode() { -# 获取当前的 worker_processes 设置值 -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# 根据值设置模式信息 -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # 检查 MySQL 配置文件中是否包含 4096M + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info=" 高性能模式" + else + mode_info=" 标准模式" + fi @@ -2204,7 +2324,7 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" # 检查 zstd 是否开启且未被注释(整行以 zstd on; 开头) if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then @@ -2233,7 +2353,7 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear send_stats "优化LDNMP环境" @@ -2252,9 +2372,11 @@ web_optimization() { 1) send_stats "站点标准模式" - # nginx调优 - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf + # php调优 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2282,7 +2404,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced @@ -2293,8 +2414,10 @@ web_optimization() { send_stats "站点高性能模式" # nginx调优 - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf # php调优 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2321,7 +2444,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_web_server echo "LDNMP环境已设置成 高性能模式" @@ -2372,7 +2494,7 @@ web_optimization() { check_docker_app() { - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then check_docker="${gl_lv}已安装${gl_bai}" else check_docker="${gl_hui}未安装${gl_bai}" @@ -2383,7 +2505,7 @@ check_docker_app() { # check_docker_app() { -# if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then # check_docker="${gl_lv}已安装${gl_bai}" # else # check_docker="${gl_hui}未安装${gl_bai}" @@ -2423,54 +2545,61 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. 区域检查 + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # 获取容器的创建时间和镜像名称 + # 2. 获取本地镜像信息 local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) - - # 提取镜像仓库和标签 - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} + [[ -z "$container_info" ]] && return - # 默认标签为 latest - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" - - # 添加对官方镜像的支持 - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. 智能路由判断 + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- 场景 A: 镜像在 GitHub (ghcr.io) --- + # 提取仓库路径,例如 ghcr.io/onexru/oneimg -> onexru/oneimg + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # 注意:ghcr.io 的 API 比较复杂,通常最快的方法是查 GitHub Repo 的 Release + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- 场景 B: 特殊指定 (即便在 Docker Hub,也想通过 GitHub Release 判断) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # 从 Docker Hub API 获取镜像发布时间 - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- 场景 C: 标准 Docker Hub --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # 验证获取的时间 - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # 比较时间戳 - if [[ $container_created_ts -lt $last_updated_ts ]]; then + # 4. 时间戳对比 + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 @@ -2705,16 +2834,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2727,7 +2873,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2748,7 +2894,8 @@ while true; do read -e -p "请输入你的选择: " choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "输入应用对外服务端口,回车默认使用${docker_port}端口: " app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port @@ -2756,10 +2903,9 @@ while true; do install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id clear echo "$docker_name 已经安装完成" @@ -2773,8 +2919,8 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id clear echo "$docker_name 已经安装完成" @@ -2789,8 +2935,8 @@ while true; do docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" send_stats "卸载$docker_name" ;; @@ -2840,7 +2986,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2861,36 +3007,41 @@ docker_app_plus() { read -e -p "输入你的选择: " choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "输入应用对外服务端口,回车默认使用${docker_port}端口: " app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id + send_stats "$app_name 安装" ;; + 2) docker_app_update - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + add_app_id + send_stats "$app_name 更新" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_name 卸载" ;; + 5) echo "${docker_name}域名访问设置" send_stats "${docker_name}域名访问设置" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) echo "域名格式 example.com 不带https://" @@ -2940,7 +3091,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2949,7 +3100,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2959,7 +3110,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -3005,52 +3156,41 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx +} + +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}已安装${gl_bai}" + else + check_f2b_status="${gl_hui}未安装${gl_bai}" + fi } f2b_install_sshd() { - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf - else + fi + + if command -v apt &>/dev/null; then install rsyslog systemctl start rsyslog systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog fi - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } f2b_sshd() { @@ -3133,8 +3273,7 @@ send_stats "安装LDNMP环境" root_use clear echo -e "${gl_huang}LDNMP环境未安装,开始安装LDNMP环境...${gl_bai}" -check_disk_space 3 -check_port +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3150,8 +3289,7 @@ send_stats "安装nginx环境" root_use clear echo -e "${gl_huang}nginx未安装,开始安装nginx环境...${gl_bai}" -check_disk_space 1 -check_port +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3201,10 +3339,21 @@ ldnmp_web_on() { } nginx_web_on() { - clear - echo "您的 $webname 搭建好了!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + echo "您的 $webname 搭建好了!" + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3221,40 +3370,38 @@ ldnmp_wp() { fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# echo "数据库名: $dbname" -# echo "用户名: $dbuse" -# echo "密码: $dbusepasswd" -# echo "数据库地址: mysql" -# echo "表前缀: wp_" } + ldnmp_Proxy() { clear webname="反向代理-IP+端口" @@ -3267,21 +3414,43 @@ ldnmp_Proxy() { if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "请输入你的反代IP: " reverseproxy + read -e -p "请输入你的反代IP (回车默认本机IP 127.0.0.1): " reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then read -e -p "请输入你的反代端口: " port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3292,8 +3461,6 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" send_stats "安装$webname" echo "开始部署 $webname" @@ -3301,32 +3468,36 @@ ldnmp_Proxy_backend() { add_yuming fi - # 获取用户输入的多个IP:端口(用空格分隔) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then read -e -p "请输入你的多个反代IP+端口用空格隔开(例如 127.0.0.1:3000 127.0.0.1:3002): " reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # 动态生成 upstream 配置 upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # 替换模板中的占位符 sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3334,6 +3505,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "服务名" "通信类型" "本机地址" "后端地址" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # 服务名取文件名 + service_name=$(basename "$conf" .conf) + + # 获取 upstream 块中的 server 后端 IP:端口 + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # 获取 listen 端口 + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # 默认本地 IP + ip_address + local_ip="$ipv4_address" + + # 获取通信类型,优先从文件名后缀或内容判断 + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # 拼接监听 IP:端口 + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "Stream四层代理" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "Stream四层代理转发工具 $check_docker $update_status" + echo "NGINX Stream 是 NGINX 的 TCP/UDP 代理模块,用于实现高性能的 传输层流量转发和负载均衡。" + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. 安装 2. 更新 3. 卸载" + echo "------------------------" + echo "4. 添加转发服务 5. 修改转发服务 6. 删除转发服务" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "安装Stream四层代理" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "更新Stream四层代理" + ;; + 3) + read -e -p "确定要删除 nginx 容器吗?这可能会影响网站功能!(y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "更新Stream四层代理" + echo "nginx 容器已删除。" + else + echo "操作已取消。" + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "添加四层代理" + ;; + 5) + send_stats "编辑转发配置" + read -e -p "请输入你要编辑的服务名: " stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "修改四层代理" + ;; + 6) + send_stats "删除转发配置" + read -e -p "请输入你要删除的服务名: " stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "删除四层代理" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="Stream四层代理-负载均衡" + + send_stats "安装$webname" + echo "开始部署 $webname" + + # 获取代理名称 + read -rp "请输入代理转发名称 (如 mysql_proxy): " proxy_name + if [ -z "$proxy_name" ]; then + echo "名称不能为空"; return 1 + fi + + # 获取监听端口 + read -rp "请输入本机监听端口 (如 3306): " listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "端口必须是数字"; return 1 + fi + + echo "请选择协议类型:" + echo "1. TCP 2. UDP" + read -rp "请输入序号 [1-2]: " proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "无效选择"; return 1 ;; + esac + + read -e -p "请输入你的一个或者多个后端IP+端口用空格隔开(例如 10.13.0.2:3306 10.13.0.3:3306): " reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 动态添加/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "您的 $webname 搭建好了!" + echo "------------------------" + echo "访问地址:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3351,11 +3716,11 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear send_stats "LDNMP站点管理" @@ -3363,8 +3728,7 @@ ldnmp_web_status() { echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output} 证书到期时间" + echo -e "站点: ${output} 证书到期时间" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3375,9 +3739,28 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "数据库: ${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" @@ -3391,11 +3774,11 @@ ldnmp_web_status() { echo "" echo "操作" echo "------------------------" - echo "1. 申请/更新域名证书 2. 更换站点域名" + echo "1. 申请/更新域名证书 2. 克隆站点域名" echo "3. 清理站点缓存 4. 创建关联站点" echo "5. 查看访问日志 6. 查看错误日志" echo "7. 编辑全局配置 8. 编辑站点配置" - echo "9. 管理站点数据库 10. 查看站点分析报告" + echo "9. 管理站点数据库 10. 查看站点分析报告" echo "------------------------" echo "20. 删除指定站点数据" echo "------------------------" @@ -3407,30 +3790,26 @@ ldnmp_web_status() { send_stats "申请域名证书" read -e -p "请输入你的域名: " yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "更换站点域名" - echo -e "${gl_hong}强烈建议: ${gl_bai}先备份好全站数据再更换站点域名!" + send_stats "克隆站点域名" read -e -p "请输入旧域名: " oddyuming read -e -p "请输入新域名: " yuming install_certbot install_ssltls certs_status - # mysql替换 - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3441,18 +3820,15 @@ ldnmp_web_status() { done # 网站目录替换 - mv /home/web/html/$oddyuming /home/web/html/$yuming + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3513,7 +3889,7 @@ ldnmp_web_status() { 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3558,21 +3934,21 @@ while true; do install wget iptables_open panel_app_install - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id send_stats "${panelname}安装" ;; 2) panel_app_manage - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id send_stats "${panelname}控制" ;; 3) panel_app_uninstall - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt send_stats "${panelname}卸载" ;; *) @@ -3871,6 +4247,7 @@ frps_main_ports() { frps_panel() { send_stats "FRP服务端" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3901,8 +4278,8 @@ frps_panel() { install jq grep ss install_docker generate_frps_config - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP服务端已经安装完成" ;; 2) @@ -3911,8 +4288,8 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP服务端已经更新完成" ;; 3) @@ -3922,8 +4299,8 @@ frps_panel() { rm -rf /home/frp close_port 8055 8056 - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" ;; 5) @@ -3968,6 +4345,7 @@ frps_panel() { frpc_panel() { send_stats "FRP客户端" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do @@ -3997,8 +4375,8 @@ frpc_panel() { install jq grep ss install_docker configure_frpc - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP客户端已经安装完成" ;; 2) @@ -4007,8 +4385,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP客户端已经更新完成" ;; @@ -4018,8 +4396,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" ;; @@ -4050,6 +4428,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4087,26 +4466,26 @@ yt_menu_pro() { send_stats "正在安装 yt-dlp..." echo "正在安装 yt-dlp..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id echo "安装完成。按任意键继续..." read ;; 2) send_stats "正在更新 yt-dlp..." echo "正在更新 yt-dlp..." - sudo yt-dlp -U - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + yt-dlp -U + + add_app_id echo "更新完成。按任意键继续..." read ;; 3) send_stats "正在卸载 yt-dlp..." echo "正在卸载 yt-dlp..." - sudo rm -f /usr/local/bin/yt-dlp - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "卸载完成。按任意键继续..." read ;; 5) @@ -4309,9 +4688,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4321,8 +4699,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4334,6 +4712,13 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } @@ -4378,7 +4763,9 @@ while true; do ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf + chattr +i /etc/resolv.conf send_stats "手动编辑DNS配置" ;; *) @@ -4538,6 +4925,7 @@ dd_xitong() { dd_xitong_1() { echo -e "重装后初始用户名: ${gl_huang}root${gl_bai} 初始密码: ${gl_huang}LeitboGi0ro${gl_bai} 初始端口: ${gl_huang}22${gl_bai}" + echo -e "${gl_huang}重装后请及时修改初始密码,防止暴力入侵。命令行输入passwd修改密码${gl_bai}" echo -e "按任意键继续..." read -n 1 -s -r -p "" install wget @@ -4571,10 +4959,12 @@ dd_xitong() { echo "重装系统" echo "--------------------------------" echo -e "${gl_hong}注意: ${gl_bai}重装有风险失联,不放心者慎用。重装预计花费15分钟,请提前备份数据。" - echo -e "${gl_hui}感谢MollyLau大佬和bin456789大佬的脚本支持!${gl_bai} " + echo -e "${gl_hui}感谢bin456789大佬和leitbogioro大佬的脚本支持!${gl_bai} " + echo -e "${gl_hui}bin456789项目地址: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro项目地址: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4590,39 +4980,42 @@ dd_xitong() { echo "35. openSUSE Tumbleweed 36. fnos飞牛公测版" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" echo "0. 返回上一级选单" echo "------------------------" read -e -p "请选择要重装的系统: " sys_choice case "$sys_choice" in + + 1) - send_stats "重装debian 12" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "重装debian 13" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "重装debian 11" + send_stats "重装debian 12" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "重装debian 10" + send_stats "重装debian 11" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "重装debian 9" + send_stats "重装debian 10" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; @@ -4784,7 +5177,6 @@ dd_xitong() { exit ;; - 41) send_stats "重装windows11" dd_xitong_2 @@ -4792,6 +5184,7 @@ dd_xitong() { reboot exit ;; + 42) dd_xitong_2 send_stats "重装windows10" @@ -4799,6 +5192,7 @@ dd_xitong() { reboot exit ;; + 43) send_stats "重装windows7" dd_xitong_4 @@ -4808,23 +5202,25 @@ dd_xitong() { ;; 44) - send_stats "重装windows server 22" + send_stats "重装windows server 25" dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "重装windows server 19" + send_stats "重装windows server 22" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "重装windows server 16" + send_stats "重装windows server 19" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; @@ -4917,7 +5313,6 @@ bbrv3() { echo "------------------------------------------------" echo "仅支持Debian/Ubuntu" echo "请备份数据,将为你升级Linux内核开启BBR3" - echo "VPS是512M内存的,请提前添加1G虚拟内存,防止因内存不足失联!" echo "------------------------------------------------" read -e -p "确定继续吗?(Y/N): " choice @@ -5119,7 +5514,7 @@ clamav_scan() { > /home/docker/clamav/log/scan.log > /dev/null 2>&1 # 执行 Docker 命令 - docker run -it --rm \ + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5654,7 +6049,10 @@ linux_trash() { done } - +linux_fav() { +send_stats "命令收藏夹" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} # 创建备份 create_backup() { @@ -6439,7 +6837,7 @@ rsync_manager() { -linux_ps() { +linux_info() { clear send_stats "系统信息查询" @@ -6490,43 +6888,47 @@ linux_ps() { local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" echo -e "系统信息查询" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}主机名: ${gl_bai}$hostname" - echo -e "${gl_kjlan}系统版本: ${gl_bai}$os_info" - echo -e "${gl_kjlan}Linux版本: ${gl_bai}$kernel_version" + echo -e "${gl_kjlan}主机名: ${gl_bai}$hostname" + echo -e "${gl_kjlan}系统版本: ${gl_bai}$os_info" + echo -e "${gl_kjlan}Linux版本: ${gl_bai}$kernel_version" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU架构: ${gl_bai}$cpu_arch" - echo -e "${gl_kjlan}CPU型号: ${gl_bai}$cpu_info" - echo -e "${gl_kjlan}CPU核心数: ${gl_bai}$cpu_cores" - echo -e "${gl_kjlan}CPU频率: ${gl_bai}$cpu_freq" + echo -e "${gl_kjlan}CPU架构: ${gl_bai}$cpu_arch" + echo -e "${gl_kjlan}CPU型号: ${gl_bai}$cpu_info" + echo -e "${gl_kjlan}CPU核心数: ${gl_bai}$cpu_cores" + echo -e "${gl_kjlan}CPU频率: ${gl_bai}$cpu_freq" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU占用: ${gl_bai}$cpu_usage_percent%" - echo -e "${gl_kjlan}系统负载: ${gl_bai}$load" - echo -e "${gl_kjlan}物理内存: ${gl_bai}$mem_info" - echo -e "${gl_kjlan}虚拟内存: ${gl_bai}$swap_info" - echo -e "${gl_kjlan}硬盘占用: ${gl_bai}$disk_info" + echo -e "${gl_kjlan}CPU占用: ${gl_bai}$cpu_usage_percent%" + echo -e "${gl_kjlan}系统负载: ${gl_bai}$load" + echo -e "${gl_kjlan}TCP|UDP连接数: ${gl_bai}$tcp_count|$udp_count" + echo -e "${gl_kjlan}物理内存: ${gl_bai}$mem_info" + echo -e "${gl_kjlan}虚拟内存: ${gl_bai}$swap_info" + echo -e "${gl_kjlan}硬盘占用: ${gl_bai}$disk_info" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}总接收: ${gl_bai}$rx" - echo -e "${gl_kjlan}总发送: ${gl_bai}$tx" + echo -e "${gl_kjlan}总接收: ${gl_bai}$rx" + echo -e "${gl_kjlan}总发送: ${gl_bai}$tx" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}网络算法: ${gl_bai}$congestion_algorithm $queue_algorithm" + echo -e "${gl_kjlan}网络算法: ${gl_bai}$congestion_algorithm $queue_algorithm" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}运营商: ${gl_bai}$isp_info" + echo -e "${gl_kjlan}运营商: ${gl_bai}$isp_info" if [ -n "$ipv4_address" ]; then - echo -e "${gl_kjlan}IPv4地址: ${gl_bai}$ipv4_address" + echo -e "${gl_kjlan}IPv4地址: ${gl_bai}$ipv4_address" fi if [ -n "$ipv6_address" ]; then - echo -e "${gl_kjlan}IPv6地址: ${gl_bai}$ipv6_address" + echo -e "${gl_kjlan}IPv6地址: ${gl_bai}$ipv6_address" fi - echo -e "${gl_kjlan}DNS地址: ${gl_bai}$dns_addresses" - echo -e "${gl_kjlan}地理位置: ${gl_bai}$country $city" - echo -e "${gl_kjlan}系统时间: ${gl_bai}$timezone $current_time" + echo -e "${gl_kjlan}DNS地址: ${gl_bai}$dns_addresses" + echo -e "${gl_kjlan}地理位置: ${gl_bai}$country $city" + echo -e "${gl_kjlan}系统时间: ${gl_bai}$timezone $current_time" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}运行时长: ${gl_bai}$runtime" + echo -e "${gl_kjlan}运行时长: ${gl_bai}$runtime" echo @@ -6551,7 +6953,7 @@ linux_tools() { echo -e "${gl_kjlan}11. ${gl_bai}btop 现代化监控工具 ${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}ranger 文件管理工具" echo -e "${gl_kjlan}13. ${gl_bai}ncdu 磁盘占用查看工具 ${gl_kjlan}14. ${gl_bai}fzf 全局搜索工具" echo -e "${gl_kjlan}15. ${gl_bai}vim 文本编辑器 ${gl_kjlan}16. ${gl_bai}nano 文本编辑器 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系统" + echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系统 ${gl_kjlan}18. ${gl_bai}opencode AI编程助手 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}黑客帝国屏保 ${gl_kjlan}22. ${gl_bai}跑火车屏保" echo -e "${gl_kjlan}26. ${gl_bai}俄罗斯方块小游戏 ${gl_kjlan}27. ${gl_bai}贪吃蛇小游戏" @@ -6710,6 +7112,17 @@ linux_tools() { send_stats "安装git" ;; + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "安装opencode" + ;; + + 21) clear install cmatrix @@ -6738,6 +7151,7 @@ linux_tools() { nsnake send_stats "安装nsnake" ;; + 28) clear install ninvaders @@ -6763,6 +7177,8 @@ linux_tools() { clear send_stats "全部卸载" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) @@ -6820,7 +7236,7 @@ linux_bbr() { send_stats "alpine开启bbr3" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6844,53 +7260,381 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # send_stats "docker管理" - echo -e "Docker管理" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}安装更新Docker环境 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局状态 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}Docker镜像管理" - echo -e "${gl_kjlan}5. ${gl_bai}Docker网络管理" - echo -e "${gl_kjlan}6. ${gl_bai}Docker卷管理" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}7. ${gl_bai}清理无用的docker容器和镜像网络数据卷" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}8. ${gl_bai}更换Docker源" - echo -e "${gl_kjlan}9. ${gl_bai}编辑daemon.json文件" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}开启Docker-ipv6访问" - echo -e "${gl_kjlan}12. ${gl_bai}关闭Docker-ipv6访问" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}20. ${gl_bai}卸载Docker环境" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "请输入你的选择: " sub_choice + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' - case $sub_choice in - 1) - clear - send_stats "安装docker环境" - install_add_docker + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } - ;; - 2) - clear - local container_count=$(docker ps -a -q 2>/dev/null | wc -l) - local image_count=$(docker images -q 2>/dev/null | wc -l) - local network_count=$(docker network ls -q 2>/dev/null | wc -l) - local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}当前备份列表:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "无备份" + } - send_stats "docker全局状态" - echo "Docker版本" + + + # ---------------------------- + # 备份 + # ---------------------------- + backup_docker() { + send_stats "Docker备份" + + echo -e "${YELLOW}正在备份 Docker 容器...${NC}" + docker ps --format '{{.Names}}' + read -e -p "请输入要备份的容器名(多个空格分隔,回车备份全部运行中容器): " containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}没有找到容器${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# 自动生成的还原脚本" >> "$RESTORE_SCRIPT" + + # 记录已打包过的 Compose 项目路径,避免重复打包 + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}备份容器: $c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}检测到 $c 是 docker-compose 容器${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "未检测到 compose 目录,请手动输入路径: " project_dir + fi + + # 如果该 Compose 项目已经打包过,跳过 + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}Compose 项目 [$project_name] 已备份过,跳过重复打包...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose 恢复: $project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}Compose 项目 [$project_name] 已打包: ${project_dir}${NC}" + else + echo -e "${RED}未找到 docker-compose.yml,跳过此容器...${NC}" + fi + else + # 普通容器备份卷 + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "打包卷: $path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # 端口 + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # 环境变量 + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # 卷映射 + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # 镜像 + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# 还原容器: $c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # 备份 /home/docker 下的所有文件(不含子目录) + if [ -d "/home/docker" ]; then + echo -e "${BLUE}备份 /home/docker 下的文件...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}/home/docker 下的文件已打包到: ${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}备份完成: ${BACKUP_DIR}${NC}" + echo -e "${GREEN}可用还原脚本: ${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # 还原 + # ---------------------------- + restore_docker() { + + send_stats "Docker还原" + read -e -p "请输入要还原的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + + echo -e "${BLUE}开始执行还原操作...${NC}" + + install tar jq gzip + install_docker + + # --------- 优先还原 Compose 项目 --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "未找到原始路径,请输入还原目录路径: " original_path + + # 检查该 compose 项目的容器是否已经在运行 + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}Compose 项目 [$project_name] 已有容器在运行,跳过还原...${NC}" + continue + fi + + read -e -p "确认还原 Compose 项目 [$project_name] 到路径 [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "请输入新的还原路径: " original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}Compose 项目 [$project_name] 已解压到: $original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}Compose 项目 [$project_name] 还原完成!${NC}" + fi + done + + # --------- 继续还原普通容器 --------- + echo -e "${BLUE}检查并还原普通 Docker 容器...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}处理容器: $container${NC}" + + # 检查容器是否已经存在且正在运行 + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 已在运行,跳过还原...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}未找到镜像信息,跳过: $container${NC}"; continue; } + + # 端口映射 + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # 环境变量 + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # 卷映射 + 卷数据恢复 + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "恢复卷数据: $VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # 删除已存在但未运行的容器 + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 存在但未运行,删除旧容器...${NC}" + docker rm -f "$container" + fi + + # 启动容器 + echo "执行还原命令: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}未找到普通容器的备份信息${NC}" + + # 还原 /home/docker 下的文件 + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}正在还原 /home/docker 下的文件...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}/home/docker 下的文件已还原完成${NC}" + else + echo -e "${YELLOW}未找到 /home/docker 下文件的备份,跳过...${NC}" + fi + + + } + + + # ---------------------------- + # 迁移 + # ---------------------------- + migrate_docker() { + send_stats "Docker迁移" + install jq + read -e -p "请输入要迁移的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + + read -e -p "目标服务器IP: " TARGET_IP + read -e -p "目标服务器SSH用户名: " TARGET_USER + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}传输备份中...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # 使用密钥登录 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # 删除备份 + # ---------------------------- + delete_backup() { + send_stats "Docker备份文件删除" + read -e -p "请输入要删除的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}已删除备份: ${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # 主菜单 + # ---------------------------- + main_menu() { + send_stats "Docker备份迁移还原" + while true; do + clear + echo "------------------------" + echo -e "Docker备份/迁移/还原工具" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. 备份docker项目" + echo -e "2. 迁移docker项目" + echo -e "3. 还原docker项目" + echo -e "4. 删除docker项目的备份文件" + echo "------------------------" + echo -e "0. 返回上一级菜单" + echo "------------------------" + read -e -p "请选择: " choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}无效选项${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "docker管理" + echo -e "Docker管理" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}安装更新Docker环境 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局状态 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}Docker镜像管理" + echo -e "${gl_kjlan}5. ${gl_bai}Docker网络管理" + echo -e "${gl_kjlan}6. ${gl_bai}Docker卷管理" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}7. ${gl_bai}清理无用的docker容器和镜像网络数据卷" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}8. ${gl_bai}更换Docker源" + echo -e "${gl_kjlan}9. ${gl_bai}编辑daemon.json文件" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}11. ${gl_bai}开启Docker-ipv6访问" + echo -e "${gl_kjlan}12. ${gl_bai}关闭Docker-ipv6访问" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}备份/迁移/还原Docker环境" + echo -e "${gl_kjlan}20. ${gl_bai}卸载Docker环境" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "请输入你的选择: " sub_choice + + case $sub_choice in + 1) + clear + send_stats "安装docker环境" + install_add_docker + + ;; + 2) + clear + local container_count=$(docker ps -a -q 2>/dev/null | wc -l) + local image_count=$(docker images -q 2>/dev/null | wc -l) + local network_count=$(docker network ls -q 2>/dev/null | wc -l) + local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + + send_stats "docker全局状态" + echo "Docker版本" docker -v docker compose version @@ -7076,6 +7820,9 @@ linux_docker() { restart docker ;; + + + 11) clear send_stats "Docker v6 开" @@ -7088,6 +7835,11 @@ linux_docker() { docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear send_stats "Docker卸载" @@ -7157,6 +7909,7 @@ linux_test() { echo -e "${gl_kjlan}综合性测试" echo -e "${gl_kjlan}31. ${gl_bai}bench 性能测试" echo -e "${gl_kjlan}32. ${gl_bai}spiritysdx 融合怪测评 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}nodequality 融合怪测评 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -7274,9 +8027,17 @@ linux_test() { 32) send_stats "spiritysdx融合怪测评" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "nodequality融合怪测评" + clear + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion @@ -7343,7 +8104,7 @@ linux_Oracle() { local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} # 运行Docker容器 - docker run -itd --name=lookbusy --restart=always \ + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ @@ -7411,7 +8172,8 @@ linux_Oracle() { 4) clear - echo "该功能处于开发阶段,敬请期待!" + send_stats "R探长开机脚本" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7441,6 +8203,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7458,20 +8223,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}环境已安装${gl_bai} $output $db_output" + echo -e "${gl_lv}环境已安装${gl_bai} 站点: $output 数据库: $db_output" fi fi @@ -7513,7 +8278,7 @@ linux_ldnmp() { echo -e "${gl_huang}23. ${gl_bai}站点反向代理-IP+端口 ${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}站点反向代理-域名" echo -e "${gl_huang}25. ${gl_bai}安装Bitwarden密码管理平台 ${gl_huang}26. ${gl_bai}安装Halo博客网站" echo -e "${gl_huang}27. ${gl_bai}安装AI绘画提示词生成器 ${gl_huang}28. ${gl_bai}站点反向代理-负载均衡" - echo -e "${gl_huang}30. ${gl_bai}自定义静态站点" + echo -e "${gl_huang}29. ${gl_bai}Stream四层代理转发 ${gl_huang}30. ${gl_bai}自定义静态站点" echo -e "${gl_huang}------------------------" echo -e "${gl_huang}31. ${gl_bai}站点数据管理 ${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}备份全站数据" echo -e "${gl_huang}33. ${gl_bai}定时远程备份 ${gl_huang}34. ${gl_bai}还原全站数据" @@ -7544,18 +8309,23 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7581,12 +8351,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7616,12 +8389,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7659,12 +8436,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7707,12 +8488,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7733,9 +8517,13 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp @@ -7758,12 +8546,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7796,13 +8588,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7832,12 +8627,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7966,12 +8764,15 @@ linux_ldnmp() { add_yuming read -e -p "请输入跳转域名: " reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -8003,12 +8804,14 @@ linux_ldnmp() { echo -e "域名格式: ${gl_huang}google.com${gl_bai}" read -e -p "请输入你的反代域名: " fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -8024,20 +8827,17 @@ linux_ldnmp() { send_stats "安装$webname" echo "开始部署 $webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8047,15 +8847,11 @@ linux_ldnmp() { send_stats "安装$webname" echo "开始部署 $webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; @@ -8066,11 +8862,13 @@ linux_ldnmp() { echo "开始部署 $webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8093,6 +8891,10 @@ linux_ldnmp() { ;; + 29) + stream_panel + ;; + 30) clear webname="静态站点" @@ -8101,11 +8903,13 @@ linux_ldnmp() { add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8170,6 +8974,8 @@ linux_ldnmp() { case "$choice" in [Yy]) read -e -p "请输入远端服务器IP: " remote_ip + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then echo "错误: 请输入远端服务器IP。" continue @@ -8178,7 +8984,7 @@ linux_ldnmp() { if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" echo "文件已传送至远程服务器home目录。" else echo "未找到要传送的文件。" @@ -8259,7 +9065,6 @@ linux_ldnmp() { echo -e "${gl_huang}正在解压 $filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot @@ -8383,7 +9188,6 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis send_stats "更新$ldnmp_pods" echo "更新${ldnmp_pods}完成" @@ -8396,7 +9200,6 @@ linux_ldnmp() { cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8454,19 +9257,30 @@ linux_ldnmp() { linux_panel() { +local sub_choice="$1" +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi +while true; do - - while true; do + if [ -z "$sub_choice" ]; then clear echo -e "应用市场" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") # 用循环设置颜色 - for i in {1..100}; do + for i in {1..150}; do if echo "$app_numbers" | grep -q "^$i$"; then declare "color$i=${gl_lv}" else @@ -8479,2359 +9293,3832 @@ linux_panel() { echo -e "${gl_kjlan}5. ${color5}OpenList多存储文件列表程序 ${gl_kjlan}6. ${color6}Ubuntu远程桌面网页版" echo -e "${gl_kjlan}7. ${color7}哪吒探针VPS监控面板 ${gl_kjlan}8. ${color8}QB离线BT磁力下载面板" echo -e "${gl_kjlan}9. ${color9}Poste.io邮件服务器程序 ${gl_kjlan}10. ${color10}RocketChat多人在线聊天系统" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}11. ${color11}禅道项目管理软件 ${gl_kjlan}12. ${color12}青龙面板定时任务管理平台" echo -e "${gl_kjlan}13. ${color13}Cloudreve网盘 ${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}简单图床图片管理程序" echo -e "${gl_kjlan}15. ${color15}emby多媒体管理系统 ${gl_kjlan}16. ${color16}Speedtest测速面板" echo -e "${gl_kjlan}17. ${color17}AdGuardHome去广告软件 ${gl_kjlan}18. ${color18}onlyoffice在线办公OFFICE" echo -e "${gl_kjlan}19. ${color19}雷池WAF防火墙面板 ${gl_kjlan}20. ${color20}portainer容器管理面板" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}21. ${color21}VScode网页版 ${gl_kjlan}22. ${color22}UptimeKuma监控工具" echo -e "${gl_kjlan}23. ${color23}Memos网页备忘录 ${gl_kjlan}24. ${color24}Webtop远程桌面网页版 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}25. ${color25}Nextcloud网盘 ${gl_kjlan}26. ${color26}QD-Today定时任务管理框架" echo -e "${gl_kjlan}27. ${color27}Dockge容器堆栈管理面板 ${gl_kjlan}28. ${color28}LibreSpeed测速工具" echo -e "${gl_kjlan}29. ${color29}searxng聚合搜索站 ${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrism私有相册系统" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}31. ${color31}StirlingPDF工具大全 ${gl_kjlan}32. ${color32}drawio免费的在线图表软件 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}33. ${color33}Sun-Panel导航面板 ${gl_kjlan}34. ${color34}Pingvin-Share文件分享平台" echo -e "${gl_kjlan}35. ${color35}极简朋友圈 ${gl_kjlan}36. ${color36}LobeChatAI聊天聚合网站" echo -e "${gl_kjlan}37. ${color37}MyIP工具箱 ${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}小雅alist全家桶" echo -e "${gl_kjlan}39. ${color39}Bililive直播录制工具 ${gl_kjlan}40. ${color40}webssh网页版SSH连接工具" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}41. ${color41}耗子管理面板 ${gl_kjlan}42. ${color42}Nexterm远程连接工具" echo -e "${gl_kjlan}43. ${color43}RustDesk远程桌面(服务端) ${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk远程桌面(中继端) ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}45. ${color45}Docker加速站 ${gl_kjlan}46. ${color46}GitHub加速站 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}47. ${color47}普罗米修斯监控 ${gl_kjlan}48. ${color48}普罗米修斯(主机监控)" echo -e "${gl_kjlan}49. ${color49}普罗米修斯(容器监控) ${gl_kjlan}50. ${color50}补货监控工具" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}51. ${color51}PVE开小鸡面板 ${gl_kjlan}52. ${color52}DPanel容器管理面板" echo -e "${gl_kjlan}53. ${color53}llama3聊天AI大模型 ${gl_kjlan}54. ${color54}AMH主机建站管理面板" echo -e "${gl_kjlan}55. ${color55}FRP内网穿透(服务端) ${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRP内网穿透(客户端) ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}57. ${color57}Deepseek聊天AI大模型 ${gl_kjlan}58. ${color58}Dify大模型知识库 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}59. ${color59}NewAPI大模型资产管理 ${gl_kjlan}60. ${color60}JumpServer开源堡垒机" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}61. ${color61}在线翻译服务器 ${gl_kjlan}62. ${color62}RAGFlow大模型知识库" echo -e "${gl_kjlan}63. ${color63}OpenWebUI自托管AI平台 ${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}it-tools工具箱" echo -e "${gl_kjlan}65. ${color65}n8n自动化工作流平台 ${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp视频下载工具" echo -e "${gl_kjlan}67. ${color67}ddns-go动态DNS管理工具 ${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL证书管理平台" echo -e "${gl_kjlan}69. ${color69}SFTPGo文件传输工具 ${gl_kjlan}70. ${color70}AstrBot聊天机器人框架" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}71. ${color71}Navidrome私有音乐服务器 ${gl_kjlan}72. ${color72}bitwarden密码管理器 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}73. ${color73}LibreTV私有影视 ${gl_kjlan}74. ${color74}MoonTV私有影视" echo -e "${gl_kjlan}75. ${color75}Melody音乐精灵 ${gl_kjlan}76. ${color76}在线DOS老游戏" echo -e "${gl_kjlan}77. ${color77}迅雷离线下载工具 ${gl_kjlan}78. ${color78}PandaWiki智能文档管理系统" echo -e "${gl_kjlan}79. ${color79}Beszel服务器监控 ${gl_kjlan}80. ${color80}linkwarden书签管理" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}81. ${color81}JitsiMeet视频会议" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet视频会议 ${gl_kjlan}82. ${color82}gpt-load高性能AI透明代理" + echo -e "${gl_kjlan}83. ${color83}komari服务器监控工具 ${gl_kjlan}84. ${color84}Wallos个人财务管理工具" + echo -e "${gl_kjlan}85. ${color85}immich图片视频管理器 ${gl_kjlan}86. ${color86}jellyfin媒体管理系统" + echo -e "${gl_kjlan}87. ${color87}SyncTV一起看片神器 ${gl_kjlan}88. ${color88}Owncast自托管直播平台" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox文件快递 ${gl_kjlan}90. ${color90}matrix去中心化聊天协议" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea私有代码仓库 ${gl_kjlan}92. ${color92}FileBrowser文件管理器" + echo -e "${gl_kjlan}93. ${color93}Dufs极简静态文件服务器 ${gl_kjlan}94. ${color94}Gopeed高速下载工具" + echo -e "${gl_kjlan}95. ${color95}paperless文档管理平台 ${gl_kjlan}96. ${color96}2FAuth自托管二步验证器" + echo -e "${gl_kjlan}97. ${color97}WireGuard组网(服务端) ${gl_kjlan}98. ${color98}WireGuard组网(客户端)" + echo -e "${gl_kjlan}99. ${color99}DSM群晖虚拟机 ${gl_kjlan}100. ${color100}Syncthing点对点文件同步工具" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI视频生成工具 ${gl_kjlan}102. ${color102}VoceChat多人在线聊天系统" + echo -e "${gl_kjlan}103. ${color103}Umami网站统计工具 ${gl_kjlan}104. ${color104}Stream四层代理转发工具" + echo -e "${gl_kjlan}105. ${color105}思源笔记 ${gl_kjlan}106. ${color106}Drawnix开源白板工具" + echo -e "${gl_kjlan}107. ${color107}PanSou网盘搜索 ${gl_kjlan}108. ${color108}LangBot聊天机器人" + echo -e "${gl_kjlan}109. ${color109}ZFile在线网盘 ${gl_kjlan}110. ${color110}Karakeep书签管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}多格式文件转换工具 ${gl_kjlan}112. ${color112}Lucky大内网穿透工具" + echo -e "${gl_kjlan}113. ${color113}Firefox浏览器" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}第三方应用列表" + echo -e "${gl_kjlan}想要让你的应用出现在这里?查看开发者指南: ${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # 获取应用描述 + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # 检查安装状态 (匹配 appno.txt 中的 ID) + # 这里假设 appno.txt 中记录的是 base_name (即文件名) + if echo "$app_numbers" | grep -q "^$base_name$"; then + # 如果已安装:显示 base_name - 描述 [已安装] (绿色) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text [已安装]${gl_bai}" + else + # 如果未安装:正常显示 + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done + + + + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}备份全部应用数据 ${gl_kjlan}r. ${gl_bai}还原全部应用数据" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "请输入你的选择: " sub_choice + fi - case $sub_choice in - 1) - - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" - - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } - - panel_app_manage() { - bt - } + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="宝塔面板" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_manage() { + bt + } - install_panel + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } + install_panel - ;; - 2) - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" + ;; + 2|aapanel) - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } - panel_app_manage() { - bt - } + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - install_panel + panel_app_manage() { + bt + } - ;; - 3) + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + install_panel - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + ;; + 3|1p|1panel) - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - panel_app_uninstall() { - 1pctl uninstall - } + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - install_panel + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - ;; - 4) + panel_app_uninstall() { + 1pctl uninstall + } - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + install_panel - docker_rum() { + ;; + 4|npm) - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 + docker_rum() { - } + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" - docker_app + } - ;; + local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" + local docker_url="官网介绍: https://nginxproxymanager.com/" + local docker_use="echo \"初始用户名: admin@example.com\"" + local docker_passwd="echo \"初始密码: changeme\"" + local app_size="1" - 5) + docker_app - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + ;; - docker_rum() { + 5|openlist) - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 - } + docker_rum() { + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 - ;; + } - 6) - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 + local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" + local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + } - } + local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" + local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + ;; + 7|nezha) + clear + send_stats "搭建哪吒" - ;; - 7) + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "搭建哪吒" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "哪吒监控 $check_docker $update_status" - echo "开源、轻量、易用的服务器监控与运维工具" - echo "官网搭建文档: https://nezha.wiki/guide/dashboard.html" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + echo -e "哪吒监控 $check_docker $update_status" + echo "开源、轻量、易用的服务器监控与运维工具" + echo "官网搭建文档: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. 使用" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1. 使用" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent离线BT磁力下载服务" + local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "搭建邮局" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "邮局服务 $check_docker $update_status" + echo "poste.io 是一个开源的邮件服务器解决方案," + echo "视频介绍: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "端口检测" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}端口 $port 当前可用${gl_bai}" + else + echo -e "${gl_hong}端口 $port 当前不可用${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "访问地址: " + echo "https://$yuming" + fi - 9) - send_stats "搭建邮局" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. 安装 2. 更新 3. 卸载" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice - clear - echo -e "邮局服务 $check_docker $update_status" - echo "poste.io 是一个开源的邮件服务器解决方案," - echo "视频介绍: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "请设置邮箱域名 例如 mail.yuming.com : " yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "先解析这些DNS记录" + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "按任意键继续..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "端口检测" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}端口 $port 当前可用${gl_bai}" - else - echo -e "${gl_hong}端口 $port 当前不可用${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then - yuming=$(cat /home/docker/mail.txt) - echo "访问地址: " + + add_app_id + + clear + echo "poste.io已经安装完成" + echo "------------------------" + echo "您可以使用以下地址访问poste.io:" echo "https://$yuming" - fi + echo "" - echo "------------------------" - echo "1. 安装 2. 更新 3. 卸载" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "请设置邮箱域名 例如 mail.yuming.com : " yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "先解析这些DNS记录" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "按任意键继续..." - read -n 1 -s -r -p "" + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i + yuming=$(cat /home/docker/mail.txt) + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.io已经安装完成" + echo "------------------------" + echo "您可以使用以下地址访问poste.io:" + echo "https://$yuming" + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "应用已卸载" + ;; - install jq - install_docker + *) + break + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + esac + break_end + done - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + ;; - clear - echo "poste.io已经安装完成" - echo "------------------------" - echo "您可以使用以下地址访问poste.io:" - echo "https://$yuming" - echo "" + 10|rocketchat) - ;; + local app_id="10" + local app_name="Rocket.Chat聊天系统" + local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," + local app_url="官方介绍: https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - echo "poste.io已经安装完成" - echo "------------------------" - echo "您可以使用以下地址访问poste.io:" - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt - echo "应用已卸载" - ;; + clear + ip_address + echo "已经安装完成" + check_docker_app_ip + } - *) - break - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "rocket.chat已经安装完成" + check_docker_app_ip + } - esac - break_end - done + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "应用已卸载" + } - ;; + docker_app_plus + ;; - 10) - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "已经安装完成" - check_docker_app_ip - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "rocket.chat已经安装完成" - check_docker_app_ip - } - - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "应用已卸载" - } - docker_app_plus - ;; + docker_rum() { + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + } - docker_rum() { + local docker_describe="禅道是通用的项目管理软件" + local docker_url="官网介绍: https://www.zentao.net/" + local docker_use="echo \"初始用户名: admin\"" + local docker_passwd="echo \"初始密码: 123456\"" + local app_size="2" + docker_app + ;; - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 + docker_rum() { - } - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - ;; - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 + } - docker_rum() { + local docker_describe="青龙面板是一个定时任务管理平台" + local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + 13|cloudreve) + + local app_id="13" + local app_name="cloudreve网盘" + local app_text="cloudreve是一个支持多家云存储的网盘系统" + local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - } - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "应用已卸载" + } - ;; - 13) + docker_app_plus + ;; - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest + } - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + local docker_describe="简单图床是一个简单的图床程序" + local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "应用已卸载" - } + docker_rum() { - docker_app_plus - ;; + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 - docker_rum() { + local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" + local docker_url="官网介绍: https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 - } + docker_rum() { - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + } + local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" + local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; + 17|adguardhome) - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 - } + docker_rum() { - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome - ;; - 17) - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 + } - docker_rum() { - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" + local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 18|onlyoffice) - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 - ;; + docker_rum() { + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver - 18) - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 + } - docker_rum() { + local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" + local docker_url="官网介绍: https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + ;; + 19|safeline) + send_stats "搭建雷池" - } + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "雷池服务 $check_docker" + echo "雷池是长亭科技开发的WAF站点防火墙程序面板,可以反代站点进行自动化防御" + echo "视频介绍: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + echo "------------------------" + echo "1. 安装 2. 更新 3. 重置密码 4. 卸载" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice - ;; + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - 19) - send_stats "搭建雷池" + add_app_id + clear + echo "雷池WAF面板已经安装完成" + check_docker_app_ip + docker exec safeline-mgt resetadmin - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "雷池服务 $check_docker" - echo "雷池是长亭科技开发的WAF站点防火墙程序面板,可以反代站点进行自动化防御" - echo "视频介绍: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + ;; + + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "雷池WAF面板已经更新完成" check_docker_app_ip - fi - echo "" + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "如果你是默认安装目录那现在项目已经卸载。如果你是自定义安装目录你需要到安装目录下自行执行:" + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer是一个轻量级的docker容器管理面板" + local docker_url="官网介绍: https://www.portainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode是一款强大的在线代码编写工具" + local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="Uptime Kuma 易于使用的自托管监控工具" + local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos是一款轻量级、自托管的备忘录中心" + local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" + local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" + local docker_url="官网介绍: https://nextcloud.com/" + local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" + local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="dockge是一个可视化的docker-compose容器管理面板" + local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" + local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng是一个私有且隐私的搜索引擎站点" + local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="photoprism非常强大的私有相册系统" + local docker_url="官网介绍: https://www.photoprism.app/" + local docker_use="echo \"账号: admin 密码: $rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" + local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" + local docker_url="官网介绍: https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" + local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" + local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" + local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" + local docker_url="官网介绍: ${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo \"账号: admin 密码: a123456\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" + local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" + local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "小雅全家桶" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" + local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="简易在线ssh连接工具和sftp工具" + local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="耗子面板" + local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" + local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" + local docker_url="官网介绍: https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" + local docker_url="官网介绍: https://rustdesk.com/zh-cn/" + local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" + local docker_url="官网介绍: https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" + local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="普罗米修斯监控" + local app_text="Prometheus+Grafana企业级监控系统" + local app_url="官网介绍: https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名密码均为: admin" + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "应用已卸载" + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" + local docker_url="官网介绍: https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" + local docker_url="官网介绍: https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" + local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE开小鸡" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" + local docker_url="官网介绍: https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMH面板" + local panelurl="官方地址: https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="Dify知识库" + local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" + local app_url="官方网站: https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "应用已卸载" + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="新一代大模型网关与AI资产管理系统" + local app_url="官方网站: https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer开源堡垒机" + local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" + local app_url="官方介绍: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名: admin" + echo "初始密码: ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "应用已更新" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "应用已卸载" + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" + local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow知识库" + local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" + local app_url="官方网站: https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" + local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="是一款功能强大的自动化工作流平台" + local docker_url="官网介绍: https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" + local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="开源免费的 SSL 证书自动化管理平台" + local docker_url="官网介绍: https://allinssl.com" + local docker_use="echo \"安全入口: /allinssl\"" + local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" + local docker_url="官网介绍: https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" + local docker_url="官网介绍: https://astrbot.app/" + local docker_use="echo \"用户名: astrbot 密码: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="是一个轻量、高性能的音乐流媒体服务器" + local docker_url="官网介绍: https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="一个你可以控制数据的密码管理器" + local docker_url="官网介绍: https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "设置LibreTV的登录密码: " app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="免费在线视频搜索与观看平台" + local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="moontv私有影视" + local app_text="免费在线视频搜索与观看平台" + local app_url="视频介绍: https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + read -e -p "输入授权码: " shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 + + docker_rum() { + + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest + + + } + + local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" + local docker_url="官网介绍: https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + 76|dosgame) + + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 + + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest + + } + + local docker_describe="是一个中文DOS游戏合集网站" + local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + + + ;; - echo "------------------------" - echo "1. 安装 2. 更新 3. 重置密码 4. 卸载" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + 77|xunlei) - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt - clear - echo "雷池WAF面板已经安装完成" - check_docker_app_ip - docker exec safeline-mgt resetadmin + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 - ;; + docker_rum() { - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt - clear - echo "雷池WAF面板已经更新完成" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt - echo "如果你是默认安装目录那现在项目已经卸载。如果你是自定义安装目录你需要到安装目录下自行执行:" - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; + read -e -p "设置登录用户名: " app_use + read -e -p "设置登录密码: " app_passwd - esac - break_end - done + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei - ;; + } - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 + local docker_describe="迅雷你的离线高速BT磁力下载工具" + local docker_url="官网介绍: https://github.com/cnk3x/xunlei" + local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer - } + 78|PandaWiki) - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" + local app_url="官方介绍: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" - ;; + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 + docker_app_update() { + docker_app_install + } - docker_rum() { + docker_app_uninstall() { + docker_app_install + } - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server + docker_app_plus + ;; - } - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + 79|beszel) + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 - docker_rum() { + docker_rum() { - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel - } + } + local docker_describe="Beszel轻量易用的服务器监控" + local docker_url="官网介绍: https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 - docker_rum() { + 80|linkwarden) - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + local app_id="80" + local app_name="linkwarden书签管理" + local app_text="一个开源的自托管书签管理平台,支持标签、搜索和团队协作。" + local app_url="官方网站: https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - } + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + # 下载官方 docker-compose 和 env 文件 + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 + # 生成随机密钥与密码 + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - docker_rum() { + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env + # 追加管理员账号信息 + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + # 启动容器 + docker compose up -d - } + clear + echo "已经安装完成" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # 保留原本的变量 + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "应用已卸载" + } + + docker_app_plus + ;; - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) - docker_rum() { + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet视频会议" + local app_text="一个开源的安全视频会议解决方案,支持多人在线会议、屏幕共享与加密通信。" + local app_url="官方网站: https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + docker_app_install() { - } + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + } - docker_rum() { + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + } - } + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "应用已卸载" + } - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + docker_app_plus - docker_rum() { + ;; - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge - } - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 82|gpt-load) - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - docker_rum() { + docker_rum() { - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest + read -e -p "设置${docker_name}的登录密钥(sk-开头字母和数字组合)如: sk-159kejilionyyds163: " app_passwd - } + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 + local docker_describe="高性能AI接口透明代理服务" + local docker_url="官网介绍: https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng - } - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 83|komari) - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - docker_rum() { + docker_rum() { - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - } + } + local docker_describe="轻量级的自托管服务器监控工具" + local docker_url="官网介绍: https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"默认账号: admin 默认密码: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 + 84|wallos) - docker_rum() { + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + docker_rum() { - } + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest + } - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="开源个人订阅追踪器,可用于财务管理" + local docker_url="官网介绍: https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 + ;; - docker_rum() { + 85|immich) - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + local app_id="85" + local app_name="immich图片视频管理器" + local app_text="高性能自托管照片和视频管理解决方案。" + local app_url="官网介绍: https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - } + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + docker compose up -d - docker_rum() { + clear + echo "已经安装完成" + check_docker_app_ip - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + } - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "应用已卸载" + } - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 + docker_app_plus - docker_rum() { - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } + ;; - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="官网介绍: ${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 86|jellyfin) + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 + docker_rum() { - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin - docker_rum() { + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + } - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + local docker_describe="是一款开源媒体服务器软件" + local docker_url="官网介绍: https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest - } + 87|synctv) + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 38) - send_stats "小雅全家桶" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv - 39) + } - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 - fi + local docker_describe="远程一起观看电影和直播的程序。它提供了同步观影、直播、聊天等功能" + local docker_url="官网介绍: https://github.com/synctv-org/synctv" + local docker_use="echo \"初始账号和密码: root 登陆后请及时修改登录密码\"" + local docker_passwd="" + local app_size="1" + docker_app - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + ;; - docker_rum() { - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + 88|owncast) - } + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 41) + } - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" + local docker_describe="开源、免费的自建直播平台" + local docker_url="官网介绍: https://owncast.online" + local docker_use="echo \"访问地址后面带 /admin 访问管理员页面\"" + local docker_passwd="echo \"初始账号: admin 初始密码: abc123 登陆后请及时修改登录密码\"" + local app_size="1" + docker_app - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } + ;; - panel_app_manage() { - panel-cli - } - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } - install_panel + 89|file-code-box) - ;; + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 + docker_rum() { - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest - docker_rum() { + } - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + local docker_describe="匿名口令分享文本和文件,像拿快递一样取文件" + local docker_url="官网介绍: https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"访问地址后面带 /#/admin 访问管理员页面\"" + local docker_passwd="echo \"管理员密码: FileCodeBox2023\"" + local app_size="1" + docker_app - } + ;; - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 - docker_rum() { - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs + 90|matrix) - } + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 + docker_rum() { - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + add_yuming - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate + fi - docker_rum() { + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + echo "创建初始用户或管理员。请设置以下内容用户名和密码以及是否为管理员。" + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - } + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker restart matrix - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker_rum() { + } - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + local docker_describe="Matrix是一个去中心化的聊天协议" + local docker_url="官网介绍: https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 - docker_rum() { + 91|gitea) - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest + local app_id="91" - } + local app_name="gitea私有代码仓库" + local app_text="免费新一代的代码托管平台,提供接近 GitHub 的使用体验。" + local app_url="视频介绍: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_install() { - 47) + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - docker_app_install() { - prometheus_install - clear - ip_address - echo "已经安装完成" - check_docker_app_ip - echo "初始用户名密码均为: admin" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "应用已卸载" + } - rm -rf /home/docker/monitoring - echo "应用已卸载" - } + docker_app_plus - docker_app_plus - ;; + ;; - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 - docker_rum() { - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + 92|filebrowser) - } + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - docker_rum() { + } - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true + local docker_describe="是一个基于Web的文件管理器" + local docker_url="官网介绍: https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 93|dufs) + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 + docker_rum() { - docker_rum() { + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest + } - } + local docker_describe="极简静态文件服务器,支持上传下载" + local docker_url="官网介绍: https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; + 94|gopeed) - 51) - clear - send_stats "PVE开小鸡" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 + docker_rum() { - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + read -e -p "设置登录用户名: " app_use + read -e -p "设置登录密码: " app_passwd - docker_rum() { + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite + } - } + local docker_describe="分布式高速下载工具,支持多种协议" + local docker_url="官网介绍: https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + 95|paperless) - } + local app_id="95" - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local app_name="paperless文档管理平台" + local app_text="开源的电子文档管理系统,它的主要用途是把你的纸质文件数字化并管理起来。" + local app_url="视频介绍: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" - 54) + docker_app_install() { - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env - panel_app_manage() { - panel_app_install - } + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - panel_app_uninstall() { - panel_app_install - } - install_panel - ;; + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } - 55) - frps_panel - ;; + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "应用已卸载" + } - 56) - frpc_panel - ;; + docker_app_plus - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + ;; - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama - } + 96|2fauth) - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local app_id="96" + local app_name="2FAuth自托管二步验证器" + local app_text="自托管的双重身份验证 (2FA) 账户管理和验证码生成工具。" + local app_url="官网: https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" + docker_app_install() { - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + add_yuming - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } - - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "应用已卸载" - } + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth - docker_app_plus + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml - ;; + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + clear + echo "已经安装完成" + check_docker_app_ip + } - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "应用已卸载" + } - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip + docker_app_plus - } + ;; - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "应用已卸载" - } - docker_app_plus - ;; + 97|wgs) + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - 60) + docker_rum() { - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" + read -e -p "请输入组网的客户端数量 (默认 5): " COUNT + COUNT=${COUNT:-5} + read -e -p "请输入 WireGuard 网段 (默认 10.13.13.0): " NETWORK + NETWORK=${NETWORK:-10.13.13.0} - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "已经安装完成" - check_docker_app_ip - echo "初始用户名: admin" - echo "初始密码: ChangeMe" - } + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) + ip link delete wg0 &>/dev/null - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "应用已更新" - } + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "应用已卸载" - } + sleep 3 - docker_app_plus - ;; + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " - docker_rum() { + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' - } + docker restart wireguard - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + sleep 2 + echo + echo -e "${gl_huang}所有客户端二维码配置: ${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}所有客户端配置代码: ${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}个客户端配置全部输出,使用方法如下:${gl_bai}" + echo -e "${gl_lv}1. 手机下载wg的APP,扫描上方二维码,可以快速连接网络${gl_bai}" + echo -e "${gl_lv}2. Windows下载客户端,复制配置代码连接网络。${gl_bai}" + echo -e "${gl_lv}3. Linux用脚本部署WG客户端,复制配置代码连接网络。${gl_bai}" + echo -e "${gl_lv}官方客户端下载方式: https://www.wireguard.com/install/${gl_bai}" + break_end + } + local docker_describe="现代化、高性能的虚拟专用网络工具" + local docker_url="官网介绍: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + ;; - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "应用已卸载" - } + 98|wgc) - docker_app_plus + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 - ;; + docker_rum() { + mkdir -p /home/docker/wireguard/config/ - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - docker_rum() { + # 创建目录(如果不存在) + mkdir -p "$(dirname "$CONFIG_FILE")" - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + echo "请粘贴你的客户端配置,连续按两次回车保存:" - } + # 初始化变量 + input="" + empty_line_count=0 - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; + # 逐行读取用户输入 + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + # 写入配置文件 + echo "$input" > "$CONFIG_FILE" - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + echo "客户端配置已保存到 $CONFIG_FILE" - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ip link delete wg0 &>/dev/null + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + sleep 3 - docker_rum() { + docker logs wireguardc - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n + break_end - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" + } - } + local docker_describe="现代化、高性能的虚拟专用网络工具" + local docker_url="官网介绍: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 66) - yt_menu_pro - ;; + 99|dsm) - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + local app_id="99" - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local app_name="dsm群晖虚拟机" + local app_text="Docker容器中的虚拟DSM" + local app_url="官网: https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" - } + docker_app_install() { - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + read -e -p "设置 CPU 核数 (默认 2): " CPU_CORES + local CPU_CORES=${CPU_CORES:-2} - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + read -e -p "设置内存大小 (默认 4G): " RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml + + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 - docker_rum() { + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "应用已卸载" + } - } + docker_app_plus - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 - docker_rum() { + 100|syncthing) - mkdir -p /home/docker/astrbot/data + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - } + local docker_describe="开源的点对点文件同步工具,类似于 Dropbox、Resilio Sync,但完全去中心化。" + local docker_url="官网介绍: https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI视频生成工具" + local app_text="MoneyPrinterTurbo是一款使用AI大模型合成高清短视频的工具" + local app_url="官方网站: https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - docker_rum() { + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ - } + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "应用已卸载" + } + docker_app_plus - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + 102|vocechat) - } + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest + + } + + local docker_describe="是一款支持独立部署的个人云社交媒体聊天服务" + local docker_url="官网介绍: https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; - ;; + 103|umami) + local app_id="103" + local app_name="Umami网站统计工具" + local app_text="开源、轻量、隐私友好的网站分析工具,类似于GoogleAnalytics。" + local app_url="官方网站: https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - 73) + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名: admin" + echo "初始密码: umami" + } + + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "应用已卸载" + } - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 + docker_app_plus - docker_rum() { + ;; + + 104|nginx-stream) + stream_panel + ;; - read -e -p "设置LibreTV的登录密码: " app_passwd - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + 105|siyuan) - } + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + read -e -p "设置登录密码: " app_passwd + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - 74) + } - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + local docker_describe="思源笔记是一款隐私优先的知识管理系统" + local docker_url="官网介绍: https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - read -e -p "设置MoonTV的登录密码: " app_passwd - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest + 106|drawnix) - } + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix + } - 75) + local docker_describe="是一款强大的开源白板工具,集成思维导图、流程图等。" + local docker_url="官网介绍: https://github.com/plait-board/drawnix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 + ;; - docker_rum() { - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + 107|pansou) + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou是一个高性能的网盘资源搜索API服务。" + local docker_url="官网介绍: https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest - } + 108|langbot) + local app_id="108" + local app_name="LangBot聊天机器人" + local app_text="是一个开源的大语言模型原生即时通信机器人开发平台" + local app_url="官方网站: https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - ;; + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - 77) + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "应用已卸载" + } - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 + docker_app_plus - docker_rum() { + ;; - read -e -p "设置${docker_name}的登录用户名: " app_use - read -e -p "设置${docker_name}的登录密码: " app_passwd - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + 109|zfile) - } + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - 78) + } - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + local docker_describe="是一个适用于个人或小团队的在线网盘程序。" + local docker_url="官网介绍: https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + ;; - docker_app_update() { - docker_app_install - } + 110|karakeep) + local app_id="110" + local app_name="karakeep书签管理" + local app_text="是一款可自行托管的书签应用,带有人工智能功能,专为数据囤积者而设计。" + local app_url="官方网站: https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker_app_uninstall() { - docker_app_install - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml - docker_app_plus - ;; + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "应用已卸载" + } - 79) + docker_app_plus - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + ;; - docker_rum() { - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel - } + 111|convertx) - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - ;; + docker_rum() { + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} - 80) - local app_name="linkwarden书签管理" - local app_text="一个开源的自托管书签管理平台,支持标签、搜索和团队协作。" - local app_url="官方网站: https://linkwarden.app/" - local docker_name="linkwarden-linkwarden-1" - local docker_port="8080" - local app_size="3" + } - docker_app_install() { - install git openssl - mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden + local docker_describe="是一个功能强大的多格式文件转换工具(支持文档、图像、音频视频等)强烈建议添加域名访问" + local docker_url="项目地址: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - # 下载官方 docker-compose 和 env 文件 - curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml - curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" + ;; - # 生成随机密钥与密码 - local ADMIN_EMAIL="admin@example.com" - local ADMIN_PASSWORD=$(openssl rand -hex 8) - sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env - sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env - sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env - sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env + 112|lucky) - # 追加管理员账号信息 - echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env - echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # 由于 Lucky 使用 host 网络模式,这里的端口仅作记录/说明参考,实际由应用自身控制(默认16601) + local docker_port=8112 - sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + docker_rum() { - # 启动容器 - docker compose up -d + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - clear - echo "已经安装完成" - check_docker_app_ip + echo "正在等待 Lucky 初始化..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - } + } - docker_app_update() { - cd /home/docker/linkwarden && docker compose down --rmi all - curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml - curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" - - # 保留原本的变量 - source .env - mv .env.new .env - echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env - echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env - echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env - echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env - echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env - echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env - sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - - docker compose up -d - } + local docker_describe="Lucky 是一个大内网穿透及端口转发管理工具,支持 DDNS、反向代理、WOL 等功能。" + local docker_url="项目地址: https://github.com/gdy666/lucky" + local docker_use="echo \"默认账号密码: 666\"" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_uninstall() { - cd /home/docker/linkwarden && docker compose down --rmi all - rm -rf /home/docker/linkwarden - echo "应用已卸载" - } + ;; - docker_app_plus - ;; + 113|firefox) + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 + docker_rum() { - 81) - local app_name="JitsiMeet视频会议" - local app_text="一个开源的安全视频会议解决方案,支持多人在线会议、屏幕共享与加密通信。" - local app_url="官方网站: https://jitsi.org/" - local docker_name="jitsi" - local docker_port="8081" - local app_size="3" + read -e -p "设置登录密码: " admin_password - docker_app_install() { + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - add_yuming - mkdir -p /home/docker/jitsi && cd /home/docker/jitsi - wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) - unzip "$(ls -t | head -n 1)" - cd "$(ls -dt */ | head -n 1)" - cp env.example .env - ./gen-passwords.sh - mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} - sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env - sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env - docker compose up -d + local docker_describe="是一个运行在 Docker 中的 Firefox 浏览器,支持通过网页直接访问桌面版浏览器界面。" + local docker_url="项目地址: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" + ;; - } - docker_app_update() { - cd /home/docker/jitsi - cd "$(ls -dt */ | head -n 1)" - docker compose down --rmi all - docker compose up -d + b) + clear + send_stats "全部应用备份" - } + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}正在备份 $backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_app_uninstall() { - cd /home/docker/jitsi - cd "$(ls -dt */ | head -n 1)" - docker compose down --rmi all - rm -rf /home/docker/jitsi - echo "应用已卸载" - } + while true; do + clear + echo "备份文件已创建: /$backup_filename" + read -e -p "要传送备份数据到远程服务器吗?(Y/N): " choice + case "$choice" in + [Yy]) + read -e -p "请输入远端服务器IP: " remote_ip + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - docker_app_plus + if [ -z "$remote_ip" ]; then + echo "错误: 请输入远端服务器IP。" + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "文件已传送至远程服务器/根目录。" + else + echo "未找到要传送的文件。" + fi + break + ;; + *) + echo "注意: 目前备份仅包含docker项目,不包含宝塔,1panel等建站面板的数据备份。" + break + ;; + esac + done - ;; + ;; + r) + root_use + send_stats "全部应用还原" + echo "可用的应用备份" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "回车键还原最新的备份,输入备份文件名还原指定的备份,输入0退出:" filename + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # 如果用户没有输入文件名,使用最新的压缩包 + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}正在解压 $filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "应用数据已还原,目前请手动进入指定应用菜单,更新应用,即可还原应用。" + else + echo "没有找到压缩包。" + fi + ;; - 0) - kejilion - ;; - *) - echo "无效的输入!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}错误: 未找到编号为 ${sub_choice} 的应用配置${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do @@ -11019,6 +13306,101 @@ linux_work() { +# 智能切换镜像源函数 +switch_mirror() { + # 可选参数,默认为 false + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # 获取用户国家 + local country + country=$(curl -s ipinfo.io/country) + + echo "检测到国家:$country" + + if [ "$country" = "CN" ]; then + echo "使用国内镜像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "使用官方镜像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "ssh防御" + while true; do + + check_f2b_status + echo -e "SSH防御程序 $check_f2b_status" + echo "fail2ban是一个SSH防止暴力破解工具" + echo "官网介绍: ${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. 安装防御程序" + echo "------------------------" + echo "2. 查看SSH拦截记录" + echo "3. 日志实时监控" + echo "------------------------" + echo "9. 卸载防御程序" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "请输入你的选择: " sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban防御程序已卸载" + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { @@ -11246,6 +13628,8 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root @@ -11261,13 +13645,14 @@ EOF clear echo "设置v4/v6优先级" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then echo -e "当前网络优先级设置: ${gl_huang}IPv4${gl_bai} 优先" else echo -e "当前网络优先级设置: ${gl_huang}IPv6${gl_bai} 优先" fi + echo "" echo "------------------------" echo "1. IPv4 优先 2. IPv6 优先 3. IPv6 修复工具" @@ -11278,12 +13663,10 @@ EOF case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "已切换为 IPv4 优先" - send_stats "已切换为 IPv4 优先" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 + rm -f /etc/gai.conf echo "已切换为 IPv6 优先" send_stats "已切换为 IPv6 优先" ;; @@ -11406,6 +13789,8 @@ EOF # 赋予新用户sudo权限 echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + install sudo + echo "操作已完成。" ;; @@ -11413,6 +13798,8 @@ EOF read -e -p "请输入用户名: " username # 赋予新用户sudo权限 echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) read -e -p "请输入用户名: " username @@ -11617,7 +14004,7 @@ EOF echo "选择更新源区域" echo "接入LinuxMirrors切换系统更新源" echo "------------------------" - echo "1. 中国大陆【默认】 2. 中国大陆【教育网】 3. 海外地区" + echo "1. 中国大陆【默认】 2. 中国大陆【教育网】 3. 海外地区 4. 智能切换更新源" echo "------------------------" echo "0. 返回上一级选单" echo "------------------------" @@ -11636,6 +14023,11 @@ EOF send_stats "海外源" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "智能切换更新源" + switch_mirror false false + ;; + *) echo "已取消" ;; @@ -11747,63 +14139,7 @@ EOF ;; 22) - root_use - send_stats "ssh防御" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH防御程序 $check_docker" - echo "fail2ban是一个SSH防止暴力破解工具" - echo "官网介绍: ${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1. 安装防御程序" - echo "------------------------" - echo "2. 查看SSH拦截记录" - echo "3. 日志实时监控" - echo "------------------------" - echo "9. 卸载防御程序" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "请输入你的选择: " sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2Ban防御程序已卸载" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; @@ -12052,15 +14388,15 @@ EOF 39) clear - send_stats "命令行历史记录" - bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) + linux_fav ;; 41) clear send_stats "留言板" - echo "科技lion留言板已迁移至官方社区!请在官方社区进行留言噢!" - echo "https://bbs.kejilion.pro/" + echo "访问科技lion官方留言板,您对脚本有任何想法欢迎留言交流!" + echo "https://board.kejilion.pro" + echo "公共密码: kejilion.sh" ;; 66) @@ -12070,16 +14406,18 @@ EOF echo "一条龙系统调优" echo "------------------------------------------------" echo "将对以下内容进行操作与优化" - echo "1. 更新系统到最新" + echo "1. 优化系统更新源,更新系统到最新" echo "2. 清理系统垃圾文件" echo -e "3. 设置虚拟内存${gl_huang}1G${gl_bai}" echo -e "4. 设置SSH端口号为${gl_huang}5522${gl_bai}" - echo -e "5. 开放所有端口" - echo -e "6. 开启${gl_huang}BBR${gl_bai}加速" - echo -e "7. 设置时区到${gl_huang}上海${gl_bai}" - echo -e "8. 自动优化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 国内: 223.5.5.5 ${gl_bai}" - echo -e "9. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10. Linux系统内核参数优化切换到${gl_huang}均衡优化模式${gl_bai}" + echo -e "5. 启动fail2ban防御SSH暴力破解" + echo -e "6. 开放所有端口" + echo -e "7. 开启${gl_huang}BBR${gl_bai}加速" + echo -e "8. 设置时区到${gl_huang}上海${gl_bai}" + echo -e "9. 自动优化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 国内: 223.5.5.5 ${gl_bai}" + echo -e "10. 设置网络为${gl_huang}ipv4优先${gl_bai}" + echo -e "11. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux系统内核参数优化切换到${gl_huang}均衡优化模式${gl_bai}" echo "------------------------------------------------" read -e -p "确定一键保养吗?(Y/N): " choice @@ -12088,58 +14426,54 @@ EOF clear send_stats "一条龙调优启动" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10. 更新系统到最新" + echo -e "[${gl_lv}OK${gl_bai}] 1/12. 更新系统到最新" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10. 清理系统垃圾文件" + echo -e "[${gl_lv}OK${gl_bai}] 2/12. 清理系统垃圾文件" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10. 设置虚拟内存${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 3/12. 设置虚拟内存${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10. 设置SSH端口号为${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 4/12. 设置SSH端口号为${gl_huang}5522${gl_bai}" echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10. 开放所有端口" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}] 5/12. 启动fail2ban防御SSH暴力破解" + + echo "------------------------------------------------" + echo -e "[${gl_lv}OK${gl_bai}] 6/12. 开放所有端口" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10. 开启${gl_huang}BBR${gl_bai}加速" + echo -e "[${gl_lv}OK${gl_bai}] 7/12. 开启${gl_huang}BBR${gl_bai}加速" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10. 设置时区到${gl_huang}上海${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 8/12. 设置时区到${gl_huang}上海${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10. 自动优化DNS地址${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}] 9/12. 自动优化DNS地址${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}] 10/12. 设置网络为${gl_huang}ipv4优先${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 11/12. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10. Linux系统内核参数优化" + echo -e "[${gl_lv}OK${gl_bai}] 12/12. Linux系统内核参数优化" echo -e "${gl_lv}一条龙系统调优已完成${gl_bai}" ;; @@ -12667,6 +15001,64 @@ echo "" +games_server_tools() { + + while true; do + clear + echo -e "游戏开服脚本合集" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}幻兽帕鲁开服脚本" + echo -e "${gl_kjlan}2. ${gl_bai}我的世界开服脚本" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "请输入你的选择: " sub_choice + + case $sub_choice in + + 1) send_stats "幻兽帕鲁开服脚本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh + exit + ;; + 2) send_stats "我的世界开服脚本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/mc.sh ; chmod +x mc.sh ; ./mc.sh + exit + ;; + + 0) + kejilion + ;; + + *) + echo "无效的输入!" + ;; + esac + break_end + + done + + +} + + + + + + + + + + + + + + + + + + + + kejilion_update() { @@ -12787,8 +15179,7 @@ echo -e "${gl_kjlan}12. ${gl_bai}后台工作区" echo -e "${gl_kjlan}13. ${gl_bai}系统工具" echo -e "${gl_kjlan}14. ${gl_bai}服务器集群控制" echo -e "${gl_kjlan}15. ${gl_bai}广告专栏" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}幻兽帕鲁开服脚本" +echo -e "${gl_kjlan}16. ${gl_bai}游戏开服脚本合集" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}脚本更新" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -12797,7 +15188,7 @@ echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "请输入你的选择: " choice case $choice in - 1) linux_ps ;; + 1) linux_info ;; 2) clear ; send_stats "系统更新" ; linux_update ;; 3) clear ; send_stats "系统清理" ; linux_clean ;; 4) linux_tools ;; @@ -12814,10 +15205,7 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "幻兽帕鲁开服脚本" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; *) echo "无效的输入!" ;; @@ -12856,6 +15244,7 @@ echo "软件状态查看 k status sshd | k 状态 sshd " echo "软件开机启动 k enable docker | k autostart docke | k 开机启动 docker " echo "域名证书申请 k ssl" echo "域名证书到期查询 k ssl ps" +echo "docker管理平面 k docker" echo "docker环境安装 k docker install |k docker 安装" echo "docker容器管理 k docker ps |k docker 容器" echo "docker镜像管理 k docker img |k docker 镜像" @@ -12864,13 +15253,17 @@ echo "LDNMP缓存清理 k web cache" echo "安装WordPress k wp |k wordpress |k wp xxx.com" echo "安装反向代理 k fd |k rp |k 反代 |k fd xxx.com" echo "安装负载均衡 k loadbalance |k 负载均衡" +echo "安装L4负载均衡 k stream |k L4负载均衡" echo "防火墙面板 k fhq |k 防火墙" echo "开放端口 k dkdk 8080 |k 打开端口 8080" echo "关闭端口 k gbdk 7800 |k 关闭端口 7800" echo "放行IP k fxip 127.0.0.0/8 |k 放行IP 127.0.0.0/8" echo "阻止IP k zzip 177.5.25.36 |k 阻止IP 177.5.25.36" - - +echo "命令收藏夹 k fav | k 命令收藏夹" +echo "应用市场管理 k app" +echo "应用编号快捷管理 k app 26 | k app 1panel | k app npm" +echo "fail2ban管理 k fail2ban | k f2b" +echo "显示系统信息 k info" } @@ -12952,6 +15345,11 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift send_stats "快速设置虚拟内存" @@ -13002,6 +15400,10 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift send_stats "软件状态查看" @@ -13061,7 +15463,7 @@ else docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -13081,6 +15483,22 @@ else fi ;; + + app) + shift + send_stats "应用$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/custom_mysql_config-1.cnf b/custom_mysql_config-1.cnf index d3f5a12fa..5261b859f 100644 --- a/custom_mysql_config-1.cnf +++ b/custom_mysql_config-1.cnf @@ -1 +1,44 @@ +[mysqld] + +# 连接和线程管理 +max_connections = 200 # 小机型避免连接风暴 +thread_cache_size = 64 +interactive_timeout = 20 +wait_timeout = 20 + +# InnoDB设置 +innodb_buffer_pool_size = 512M # 2G RAM 中最重要的分配,留足系统空间 +innodb_buffer_pool_instances = 1 # 小内存不需要分片 +innodb_log_buffer_size = 8M +innodb_redo_log_capacity = 64M +innodb_lock_wait_timeout = 30 +innodb_file_per_table = 1 +innodb_flush_log_at_trx_commit = 1 +innodb_io_capacity = 400 # 普通SSD预期值 +innodb_io_capacity_max = 800 + +# 缓存和表限制 +table_open_cache = 512 +open_files_limit = 20000 +tmp_table_size = 32M +max_heap_table_size = 32M +max_allowed_packet = 32M + +# 缓冲区大小 +sort_buffer_size = 2M +read_buffer_size = 512K +join_buffer_size = 1M + +# 日志管理 +log_error_verbosity = 3 +slow_query_log = 1 +slow_query_log_file = /var/log/mysql/slow.log +long_query_time = 1 +log_queries_not_using_indexes = 1 + +# 其他 +sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION +performance_schema=ON +disable-log-bin + diff --git a/custom_mysql_config.cnf b/custom_mysql_config.cnf index a4240a45c..00aedc27a 100644 --- a/custom_mysql_config.cnf +++ b/custom_mysql_config.cnf @@ -42,3 +42,4 @@ log_queries_not_using_indexes = 1 # ⭐记录无索引扫描 # 其他 sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION performance_schema=ON # ⭐生产环境推荐打开,监控分析好用 +disable-log-bin diff --git a/en/kejilion.sh b/en/kejilion.sh index 4648ca502..c2f4a0387 100644 --- a/en/kejilion.sh +++ b/en/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.3" +sh_v="4.3.1" gl_hui='\e[37m' @@ -34,7 +34,7 @@ quanju_canshu -# Define a function to execute commands +# Define a function to execute the command run_command() { if [ "$zhushi" -eq 0 ]; then "$@" @@ -57,9 +57,9 @@ CheckFirstRun_true() { -# Functions that collect function buried point information, record the current script version number, usage time, system version, CPU architecture, the country of the machine and the function name used by the user. They absolutely do not involve any sensitive information, please rest assured! Please believe me! -# Why do we need to design this function? The purpose is to better understand the functions that users like to use, and further optimize the functions to launch more functions that meet user needs. -# For the full text, you can search for the send_stats function call location, transparent and open source, and you can refuse to use it if you have any concerns. +# This function collects function buried information and records the current script version number, usage time, system version, CPU architecture, machine country and function name used by the user. It does not involve any sensitive information, so don’t worry! Please believe me! +# Why is this function designed? The purpose is to better understand the functions that users like to use, and to further optimize the functions and launch more functions that meet user needs. +# The full text can be searched for the send_stats function call location. It is transparent and open source. If you have any concerns, you can refuse to use it. @@ -111,22 +111,22 @@ CheckFirstRun_false() { fi } -# Prompt the user to agree to the terms +# Prompt user to agree to terms UserLicenseAgreement() { clear - echo -e "${gl_kjlan}Welcome to the Tech lion script toolbox${gl_bai}" - echo "For the first time using the script, please read and agree to the user license agreement." + echo -e "${gl_kjlan}Welcome to the technology lion script toolbox${gl_bai}" + echo "When using the script for the first time, please read and agree to the User License Agreement." echo "User License Agreement: https://blog.kejilion.pro/user-license-agreement/" echo -e "----------------------" read -r -p "Do you agree to the above terms? (y/n):" user_input if [ "$user_input" = "y" ] || [ "$user_input" = "Y" ]; then - send_stats "License consent" + send_stats "License agreement" sed -i 's/^permission_granted="false"/permission_granted="true"/' ~/kejilion.sh sed -i 's/^permission_granted="false"/permission_granted="true"/' /usr/local/bin/k else - send_stats "Rejection of permission" + send_stats "permission denied" clear exit fi @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -170,7 +170,7 @@ ipv6_address=$(curl -s --max-time 1 https://v6.ipinfo.io/ip && echo) install() { if [ $# -eq 0 ]; then - echo "Package parameters are not provided!" + echo "No package parameters provided!" return 1 fi @@ -213,30 +213,40 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then - echo -e "${gl_huang}hint:${gl_bai}Insufficient disk space!" + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then + echo -e "${gl_huang}hint:${gl_bai}Not enough disk space!" echo "Current available space: $((available_space_mb/1024))G" - echo "Minimum demand space:${required_gb}G" - echo "The installation cannot be continued. Please clean the disk space and try again." - send_stats "Insufficient disk space" + echo "Minimum required space:${required_gb}G" + echo "The installation cannot continue. Please clear the disk space and try again." + send_stats "Not enough disk space" break_end kejilion fi } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { if [ $# -eq 0 ]; then - echo "Package parameters are not provided!" + echo "No package parameters provided!" return 1 fi @@ -279,7 +289,7 @@ systemctl() { } -# Restart the service +# Restart service restart() { systemctl restart "$1" if [ $? -eq 0 ]; then @@ -289,13 +299,13 @@ restart() { fi } -# Start the service +# Start service start() { systemctl start "$1" if [ $? -eq 0 ]; then - echo "$1The service has been started." + echo "$1The service has started." else - echo "Error: Start$1Service failed." + echo "Error: start$1Service failed." fi } @@ -303,9 +313,9 @@ start() { stop() { systemctl stop "$1" if [ $? -eq 0 ]; then - echo "$1Service has been stopped." + echo "$1Service has stopped." else - echo "Error: Stop$1Service failed." + echo "Error: stop$1Service failed." fi } @@ -313,9 +323,9 @@ stop() { status() { systemctl status "$1" if [ $? -eq 0 ]; then - echo "$1The service status is displayed." + echo "$1Service status is shown." else - echo "Error: Unable to display$1Service status." + echo "Error: cannot be displayed$1Service status." fi } @@ -328,7 +338,7 @@ enable() { /bin/systemctl enable "$SERVICE_NAME" fi - echo "$SERVICE_NAMESet to power on." + echo "$SERVICE_NAMEIt has been set to start automatically at boot." } @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,18 +417,31 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } @@ -426,61 +449,8 @@ install_add_docker_cn install_add_docker() { echo -e "${gl_huang}Installing docker environment...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -504,7 +474,7 @@ while true; do echo "Docker container list" docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" echo "" - echo "Container operation" + echo "Container operations" echo "------------------------" echo "1. Create a new container" echo "------------------------" @@ -514,37 +484,37 @@ while true; do echo "5. Restart the specified container 9. Restart all containers" echo "------------------------" echo "11. Enter the specified container 12. View the container log" - echo "13. View container network 14. View container occupancy" + echo "13. Check the container network 14. Check the container occupancy" echo "------------------------" - echo "15. Turn on container port access 16. Turn off container port access" + echo "15. Enable container port access 16. Close container port access" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) send_stats "Create a new container" - read -e -p "Please enter the creation command:" dockername + read -e -p "Please enter the create command:" dockername $dockername ;; 2) send_stats "Start the specified container" - read -e -p "Please enter the container name (multiple container names separated by spaces):" dockername + read -e -p "Please enter the container name (please separate multiple container names with spaces):" dockername docker start $dockername ;; 3) - send_stats "Stop the specified container" - read -e -p "Please enter the container name (multiple container names separated by spaces):" dockername + send_stats "Stop specified container" + read -e -p "Please enter the container name (please separate multiple container names with spaces):" dockername docker stop $dockername ;; 4) send_stats "Delete the specified container" - read -e -p "Please enter the container name (multiple container names separated by spaces):" dockername + read -e -p "Please enter the container name (please separate multiple container names with spaces):" dockername docker rm -f $dockername ;; 5) send_stats "Restart the specified container" - read -e -p "Please enter the container name (multiple container names separated by spaces):" dockername + read -e -p "Please enter the container name (please separate multiple container names with spaces):" dockername docker restart $dockername ;; 6) @@ -576,11 +546,11 @@ while true; do 11) send_stats "Enter the container" read -e -p "Please enter the container name:" dockername - docker exec -it $dockername /bin/sh + docker exec $dockername /bin/sh break_end ;; 12) - send_stats "View container log" + send_stats "View container logs" read -e -p "Please enter the container name:" dockername docker logs $dockername break_end @@ -590,7 +560,7 @@ while true; do echo "" container_ids=$(docker ps -q) echo "------------------------------------------------------------" - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "Container name" "network name" "IP address" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") local container_name=$(echo "$container_info" | awk '{print $1}') @@ -651,27 +621,27 @@ while true; do echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Pull the mirror" - read -e -p "Please enter the mirror name (please separate multiple mirror names with spaces):" imagenames + send_stats "Pull image" + read -e -p "Please enter the image name (please separate multiple image names with spaces):" imagenames for name in $imagenames; do - echo -e "${gl_huang}Getting the image:$name${gl_bai}" + echo -e "${gl_huang}Obtaining image:$name${gl_bai}" docker pull $name done ;; 2) - send_stats "Update the image" - read -e -p "Please enter the mirror name (please separate multiple mirror names with spaces):" imagenames + send_stats "Update image" + read -e -p "Please enter the image name (please separate multiple image names with spaces):" imagenames for name in $imagenames; do - echo -e "${gl_huang}Updated image:$name${gl_bai}" + echo -e "${gl_huang}Updating image:$name${gl_bai}" docker pull $name done ;; 3) - send_stats "Delete the mirror" - read -e -p "Please enter the mirror name (please separate multiple mirror names with spaces):" imagenames + send_stats "Delete image" + read -e -p "Please enter the image name (please separate multiple image names with spaces):" imagenames for name in $imagenames; do docker rmi -f $name done @@ -759,11 +729,11 @@ install_crontab() { ;; esac else - echo "The operating system cannot be determined." + echo "Unable to determine operating system." return fi - echo -e "${gl_lv}crontab is installed and the cron service is running.${gl_bai}" + echo -e "${gl_lv}crontab is installed and cron service is running.${gl_bai}" } @@ -775,15 +745,15 @@ docker_ipv6_on() { local CONFIG_FILE="/etc/docker/daemon.json" local REQUIRED_IPV6_CONFIG='{"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}' - # Check if the configuration file exists, create the file and write the default settings if it does not exist + # Check if the configuration file exists, if not create the file and write the default settings if [ ! -f "$CONFIG_FILE" ]; then echo "$REQUIRED_IPV6_CONFIG" | jq . > "$CONFIG_FILE" restart docker else - # Use jq to handle updates of configuration files + # Use jq to handle configuration file updates local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # Check whether the current configuration already has ipv6 settings + # Check if the current configuration already has ipv6 settings local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq '.ipv6 // false') # Update configuration and enable IPv6 @@ -793,7 +763,7 @@ docker_ipv6_on() { UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq '. + {"fixed-cidr-v6": "2001:db8:1::/64"}') fi - # Comparing original configuration with new configuration + # Compare original configuration to new configuration if [[ "$ORIGINAL_CONFIG" == "$UPDATED_CONFIG" ]]; then echo -e "${gl_huang}IPv6 access is currently enabled${gl_bai}" else @@ -812,20 +782,20 @@ docker_ipv6_off() { # Check if the configuration file exists if [ ! -f "$CONFIG_FILE" ]; then - echo -e "${gl_hong}The configuration file does not exist${gl_bai}" + echo -e "${gl_hong}Configuration file does not exist${gl_bai}" return fi - # Read the current configuration + # Read current configuration local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # Use jq to handle updates of configuration files + # Use jq to handle configuration file updates local UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq 'del(.["fixed-cidr-v6"]) | .ipv6 = false') - # Check the current ipv6 status + # Check current ipv6 status local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq -r '.ipv6 // false') - # Comparing original configuration with new configuration + # Compare original configuration to new configuration if [[ "$CURRENT_IPV6" == "false" ]]; then echo -e "${gl_huang}IPv6 access is currently closed${gl_bai}" else @@ -877,23 +847,23 @@ open_port() { install iptables for port in "${ports[@]}"; do - # Delete existing closing rules + # Delete existing shutdown rules iptables -D INPUT -p tcp --dport $port -j DROP 2>/dev/null iptables -D INPUT -p udp --dport $port -j DROP 2>/dev/null - # Add Open Rules + # Add open rule if ! iptables -C INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j ACCEPT fi if ! iptables -C INPUT -p udp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p udp --dport $port -j ACCEPT - echo "The port has been opened$port" + echo "Port opened$port" fi done save_iptables_rules - send_stats "The port has been opened" + send_stats "Port opened" } @@ -911,7 +881,7 @@ close_port() { iptables -D INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null iptables -D INPUT -p udp --dport $port -j ACCEPT 2>/dev/null - # Add a close rule + # Add shutdown rule if ! iptables -C INPUT -p tcp --dport $port -j DROP 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j DROP fi @@ -926,7 +896,7 @@ close_port() { iptables -D INPUT -i lo -j ACCEPT 2>/dev/null iptables -D FORWARD -i lo -j ACCEPT 2>/dev/null - # Insert new rules to first + # Insert new rule into the first one iptables -I INPUT 1 -i lo -j ACCEPT iptables -I FORWARD 1 -i lo -j ACCEPT @@ -948,7 +918,7 @@ allow_ip() { # Delete existing blocking rules iptables -D INPUT -s $ip -j DROP 2>/dev/null - # Add allow rules + # Add allow rule if ! iptables -C INPUT -s $ip -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -s $ip -j ACCEPT echo "Released IP$ip" @@ -972,7 +942,7 @@ block_ip() { # Delete existing allow rules iptables -D INPUT -s $ip -j ACCEPT 2>/dev/null - # Add blocking rules + # Add blocking rule if ! iptables -C INPUT -s $ip -j DROP 2>/dev/null; then iptables -I INPUT 1 -s $ip -j DROP echo "IP blocked$ip" @@ -990,7 +960,7 @@ block_ip() { enable_ddos_defense() { - # Turn on defense DDoS + # Turn on DDoS protection iptables -A DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT iptables -A DOCKER-USER -p tcp --syn -j DROP iptables -A DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT @@ -1003,9 +973,9 @@ enable_ddos_defense() { send_stats "Turn on DDoS defense" } -# Turn off DDoS Defense +# Turn off DDoS defense disable_ddos_defense() { - # Turn off defense DDoS + # Turn off DDoS protection iptables -D DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT 2>/dev/null iptables -D DOCKER-USER -p tcp --syn -j DROP 2>/dev/null iptables -D DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null @@ -1015,115 +985,108 @@ disable_ddos_defense() { iptables -D INPUT -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null iptables -D INPUT -p udp -j DROP 2>/dev/null - send_stats "Turn off DDoS Defense" + send_stats "Turn off DDoS defense" } -# Functions that manage national IP rules +# Functions to manage national IP rules manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # Create if ipset does not exist - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # Download IP area file - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "Error: Download$country_codeIP zone file failed" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # Add IP to ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "Error: Download$country_codeIP zone file failed" + continue + fi - # Block IP with iptables - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "Blocked successfully$country_codeIP address" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # Create an ipset for allowed countries (if not exist) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "Blocked successfully$country_codeIP address" + rm "${country_code,,}.zone" + ;; - # Download IP area file - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "Error: Download$country_codeIP zone file failed" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # Delete existing national rules - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "Error: Download$country_codeIP zone file failed" + continue + fi - # Add IP to ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # Only IPs in designated countries are allowed - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "Successfully only allowed$country_codeIP address" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # Delete the iptables rules for the country - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "Successfully allowed$country_codeIP address" + rm "${country_code,,}.zone" + ;; - # Destroy ipset - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "Successfully lifted$country_codeIP address restrictions" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "Removed successfully$country_codeIP address restrictions" + ;; + + *) + echo "Usage: manage_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables save_iptables_rules while true; do clear - echo "Advanced Firewall Management" - send_stats "Advanced Firewall Management" + echo "Advanced firewall management" + send_stats "Advanced firewall management" echo "------------------------" iptables -L INPUT echo "" - echo "Firewall Management" + echo "Firewall management" echo "------------------------" - echo "1. Open the specified port 2. Close the specified port" + echo "1. Open the designated port 2. Close the designated port" echo "3. Open all ports 4. Close all ports" echo "------------------------" echo "5. IP whitelist 6. IP blacklist" @@ -1131,24 +1094,24 @@ iptables_panel() { echo "------------------------" echo "11. Allow PING 12. Disable PING" echo "------------------------" - echo "13. Start DDOS Defense 14. Turn off DDOS Defense" + echo "13. Start DDOS defense 14. Turn off DDOS defense" echo "------------------------" - echo "15. Block specified country IP 16. Only specified country IPs are allowed" - echo "17. Release IP restrictions in designated countries" + echo "15. Block specified country IPs 16. Allow only specified country IPs" + echo "17. Lift IP restrictions in designated countries" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) read -e -p "Please enter the open port number:" o_port open_port $o_port - send_stats "Open a specified port" + send_stats "Open specified port" ;; 2) read -e -p "Please enter the closed port number:" c_port close_port $c_port - send_stats "Close the specified port" + send_stats "Close specified port" ;; 3) # Open all ports @@ -1185,21 +1148,21 @@ iptables_panel() { 5) # IP whitelist - read -e -p "Please enter the IP or IP segment to release:" o_ip + read -e -p "Please enter the allowed IP or IP segment:" o_ip allow_ip $o_ip ;; 6) # IP blacklist - read -e -p "Please enter the blocked IP or IP segment:" c_ip + read -e -p "Please enter the blocked IP or IP range:" c_ip block_ip $c_ip ;; 7) - # Clear the specified IP + # Clear specified IP read -e -p "Please enter the cleared IP:" d_ip iptables -D INPUT -s $d_ip -j ACCEPT 2>/dev/null iptables -D INPUT -s $d_ip -j DROP 2>/dev/null iptables-save > /etc/iptables/rules.v4 - send_stats "Clear the specified IP" + send_stats "Clear specified IP" ;; 11) # Allow PING @@ -1223,20 +1186,20 @@ iptables_panel() { ;; 15) - read -e -p "Please enter the blocked country code (such as CN, US, JP):" country_code + read -e -p "Please enter the blocked country code (multiple country codes can be separated by spaces, such as CN US JP):" country_code manage_country_rules block $country_code - send_stats "Allowed countries$country_codeIP" + send_stats "allow countries$country_codeIP" ;; 16) - read -e -p "Please enter the allowed country code (such as CN, US, JP):" country_code + read -e -p "Please enter the allowed country codes (multiple country codes can be separated by spaces, such as CN US JP):" country_code manage_country_rules allow $country_code - send_stats "Block the country$country_codeIP" + send_stats "block country$country_codeIP" ;; 17) - read -e -p "Please enter the cleared country code (such as CN, US, JP):" country_code + read -e -p "Please enter the cleared country code (multiple country codes can be separated by spaces, such as CN US JP):" country_code manage_country_rules unblock $country_code - send_stats "Clear the country$country_codeIP" + send_stats "clear country$country_codeIP" ;; *) @@ -1252,25 +1215,23 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 # Get all swap partitions in the current system local swap_partitions=$(grep -E '^/dev/' /proc/swaps | awk '{print $1}') - # Iterate over and delete all swap partitions + # Traverse and delete all swap partitions for partition in $swap_partitions; do swapoff "$partition" wipefs -a "$partition" mkswap -f "$partition" done - # Make sure /swapfile is no longer used + # Make sure /swapfile is no longer in use swapoff /swapfile - # Delete the old /swapfile + # Delete old /swapfile rm -f /swapfile # Create a new swap partition @@ -1288,7 +1249,7 @@ add_swap() { rc-update add local fi - echo -e "The virtual memory size has been resized to${gl_huang}${new_swap}${gl_bai}M" + echo -e "The virtual memory size has been adjusted to${gl_huang}${new_swap}${gl_bai}M" } @@ -1319,16 +1280,16 @@ ldnmp_v() { local nginx_version=$(echo "$nginx_version" | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e "nginx : ${gl_huang}v$nginx_version${gl_bai}" - # Get the mysql version + # Get mysql version local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local mysql_version=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SELECT VERSION();" 2>/dev/null | tail -n 1) echo -n -e " mysql : ${gl_huang}v$mysql_version${gl_bai}" - # Get the php version + # Get php version local php_version=$(docker exec php php -v 2>/dev/null | grep -oP "PHP \K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e " php : ${gl_huang}v$php_version${gl_bai}" - # Get the redis version + # Get redis version local redis_version=$(docker exec redis redis-server -v 2>&1 | grep -oP "v=+\K[0-9]+\.[0-9]+") echo -e " redis : ${gl_huang}v$redis_version${gl_bai}" @@ -1342,11 +1303,9 @@ ldnmp_v() { install_ldnmp_conf() { # Create necessary directories and files - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "stream" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # Get the country code (such as CN, US, etc.) + local country=$(curl -s ipinfo.io/country) + + # Set DNS based on country + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "Switched to IPv4 priority" +send_stats "Switched to IPv4 priority" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,11 +1392,19 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # mysql tuning + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear - echo "LDNMP environment has been installed" + echo "The LDNMP environment is installed" echo "------------------------" ldnmp_v @@ -1416,19 +1421,26 @@ install_certbot() { local cron_job="0 0 * * * ~/auto_cert_renewal.sh" crontab -l 2>/dev/null | grep -vF "$cron_job" | crontab - (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "Renewal task has been updated" + echo "The renewal task has been updated" } + + + + + + + install_ssltls() { - docker stop nginx > /dev/null 2>&1 check_port > /dev/null 2>&1 + docker stop nginx > /dev/null 2>&1 cd ~ local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1450,10 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1468,14 +1483,14 @@ install_ssltls_text() { add_ssl() { -echo -e "${gl_huang}Quickly apply for an SSL certificate, automatically renew your signature before expiration${gl_bai}" +echo -e "${gl_huang}Quickly apply for an SSL certificate and automatically renew it before expiration${gl_bai}" yuming="${1:-}" if [ -z "$yuming" ]; then add_yuming fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1484,7 +1499,7 @@ ssl_ps ssl_ps() { - echo -e "${gl_huang}The expiration of the applied certificate${gl_bai}" + echo -e "${gl_huang}Expiration status of applied certificates${gl_bai}" echo "Site information Certificate expiration time" echo "------------------------" for cert_dir in /etc/letsencrypt/live/*; do @@ -1524,22 +1539,87 @@ certs_status() { local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ -f "$file_path" ]; then - send_stats "Successful application for domain name certificate" + send_stats "Domain name certificate application successful" else - send_stats "Application for domain name certificate failed" - echo -e "${gl_hong}Notice:${gl_bai}The certificate application failed. Please check the following possible reasons and try again:" - echo -e "1. Domain name spelling error ➠ Please check whether the domain name is entered correctly" - echo -e "2. DNS resolution problem ➠ Confirm that the domain name has been correctly resolved to this server IP" - echo -e "3. Network configuration issues ➠ If you use Cloudflare Warp and other virtual networks, please temporarily shut down" - echo -e "4. Firewall restrictions ➠ Check whether port 80/443 is open to ensure verification is accessible" + send_stats "Domain name certificate application failed" + echo -e "${gl_hong}Notice:${gl_bai}Certificate application failed, please check the following possible reasons and try again:" + echo -e "1. Domain name is spelled incorrectly ➠ Please check whether the domain name is entered correctly" + echo -e "2. DNS resolution problem ➠ Confirm that the domain name has been correctly resolved to the server IP" + echo -e "3. Network configuration issues ➠ If you use virtual networks such as Cloudflare Warp, please temporarily shut down" + echo -e "4. Firewall restrictions ➠ Check whether port 80/443 is open and ensure that it is accessible" echo -e "5. The number of applications exceeds the limit ➠ Let's Encrypt has a weekly limit (5 times/domain name/week)" - echo -e "6. Domestic registration restrictions ➠ Please confirm whether the domain name is registered in mainland China" - break_end - clear - echo "Please try deploying again$webname" - add_yuming - install_ssltls - certs_status + echo -e "6. Domestic registration restrictions ➠ For mainland China environment, please confirm whether the domain name is registered" + echo "------------------------" + echo "1. Apply again 2. Import the existing certificate 3. Use HTTP access without certificate 0. Exit" + echo "------------------------" + read -e -p "Please enter your choice:" sub_choice + case $sub_choice in + 1) + send_stats "Reapply" + echo "Please try deploying again$webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "Import existing certificate" + + # Define file path + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. Enter the certificate (both ECC and RSA certificates start with BEGIN CERTIFICATE) + echo "Please paste the certificate (CRT/PEM) content (press Enter twice to end):" + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. Enter the private key (compatible with RSA, ECC, PKCS#8) + echo "Please paste the certificate private key (Private Key) content (press Enter twice to end):" + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. Intelligent verification + # Just include "BEGIN CERTIFICATE" and "PRIVATE KEY" to pass + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # Identify the current certificate type and display it + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "Detected that the ECC certificate was saved successfully." + else + echo "Detected that the RSA certificate was saved successfully." + fi + auth_method="ssl_imported" + else + echo "Error: Invalid certificate or private key format!" + certs_status + fi + + ;; + 3) + send_stats "Switch to HTTP access without a certificate" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "Withdraw application" + exit + ;; + esac fi } @@ -1557,10 +1637,44 @@ fi add_yuming() { ip_address echo -e "First resolve the domain name to the local IP:${gl_huang}$ipv4_address $ipv6_address${gl_bai}" - read -e -p "Please enter your IP or the resolved domain name:" yuming + read -e -p "Please enter your IP or resolved domain name:" yuming +} + + +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "Please enter the access/listening port, and press Enter to use 80 by default:" access_port + access_port=${access_port:-80} + fi } + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # Skip if access_port is empty + [ -z "$access_port" ] && return 0 + + # Remove all listen lines + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # Insert new listen after server { + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1685,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1694,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1635,7 +1730,7 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address @@ -1657,18 +1752,18 @@ cf_purge_cache() { # Check if the configuration file exists if [ -f "$CONFIG_FILE" ]; then - # Read API_TOKEN and zone_id from configuration files + # Read API_TOKEN and zone_id from configuration file read API_TOKEN EMAIL ZONE_IDS < "$CONFIG_FILE" - # Convert ZONE_IDS to an array + # Convert ZONE_IDS to array ZONE_IDS=($ZONE_IDS) else - # Prompt the user whether to clean the cache - read -e -p "Need to clean Cloudflare's cache? (y/n):" answer + # Prompt user whether to clear cache + read -e -p "Need to clear Cloudflare's cache? (y/n):" answer if [[ "$answer" == "y" ]]; then - echo "CF information is saved in$CONFIG_FILE, you can modify CF information later" + echo "CF information is stored in$CONFIG_FILE, you can modify the CF information later" read -e -p "Please enter your API_TOKEN:" API_TOKEN read -e -p "Please enter your CF username:" EMAIL - read -e -p "Please enter zone_id (multiple separated by spaces):" -a ZONE_IDS + read -e -p "Please enter zone_id (separate multiple with spaces):" -a ZONE_IDS mkdir -p /home/web/config/ echo "$API_TOKEN $EMAIL ${ZONE_IDS[*]}" > "$CONFIG_FILE" @@ -1685,16 +1780,15 @@ cf_purge_cache() { --data '{"purge_everything":true}' done - echo "The cache clear request has been sent." + echo "Cache clearing request has been sent." } web_cache() { - send_stats "Clean up site cache" + send_stats "Clear site cache" cf_purge_cache cd /home/web && docker compose restart - restart_redis } @@ -1704,14 +1798,14 @@ web_del() { send_stats "Delete site data" yuming_list="${1:-}" if [ -z "$yuming_list" ]; then - read -e -p "To delete site data, please enter your domain name (multiple domain names are separated by spaces):" yuming_list + read -e -p "To delete site data, please enter your domain name (separate multiple domain names with spaces):" yuming_list if [[ -z "$yuming_list" ]]; then return fi fi for yuming in $yuming_list; do - echo "Deleting the domain name:$yuming" + echo "Domain name is being deleted:$yuming" rm -r /home/web/html/$yuming > /dev/null 2>&1 rm /home/web/conf.d/$yuming.conf > /dev/null 2>&1 rm /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 @@ -1721,8 +1815,8 @@ web_del() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') - # Check whether the database exists before deleting it to avoid errors - echo "Deleting the database:$dbname" + # Check whether the database exists before deleting it to avoid errors. + echo "Deleting database:$dbname" docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE ${dbname};" > /dev/null 2>&1 done @@ -1738,23 +1832,23 @@ nginx_waf() { wget -O /home/web/nginx.conf "${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf" fi - # Decide to turn on or off WAF according to the mode parameter + # Determine whether to turn on or off WAF according to the mode parameter if [ "$mode" == "on" ]; then - # Turn on WAF: Remove comments + # Turn on WAF: remove comments sed -i 's|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity on;|\1modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 elif [ "$mode" == "off" ]; then - # Close WAF: Add Comments + # Turn off WAF: add comments sed -i 's|^load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity on;|\1# modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "Invalid parameter: Use 'on' or 'off'" + echo "Invalid argument: use 'on' or 'off'" return 1 fi - # Check nginx images and handle them according to the situation + # Check the nginx image and handle it accordingly if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1768,7 +1862,7 @@ check_waf_status() { if grep -q "^\s*#\s*modsecurity on;" /home/web/nginx.conf; then waf_status="" elif grep -q "modsecurity on;" /home/web/nginx.conf; then - waf_status=" WAF已开启" + waf_status="WAF is turned on" else waf_status="" fi @@ -1776,8 +1870,8 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then - CFmessage=" cf模式已开启" + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then + CFmessage="cf mode is on" else CFmessage="" fi @@ -1805,7 +1899,7 @@ patch_wp_memory_limit() { sed -i "/define(['\"]WP_MEMORY_LIMIT['\"].*/d" "$FILE" sed -i "/define(['\"]WP_MAX_MEMORY_LIMIT['\"].*/d" "$FILE" - # Insert a new definition before the line with "Happy publishing" + # Insert the new definition before the line containing "Happy publishing" awk -v insert="define('WP_MEMORY_LIMIT', '$MEMORY_LIMIT');\ndefine('WP_MAX_MEMORY_LIMIT', '$MAX_MEMORY_LIMIT');" \ ' /Happy publishing/ { @@ -1833,7 +1927,7 @@ patch_wp_debug() { sed -i "/define(['\"]WP_DEBUG_DISPLAY['\"].*/d" "$FILE" sed -i "/define(['\"]WP_DEBUG_LOG['\"].*/d" "$FILE" - # Insert a new definition before the line with "Happy publishing" + # Insert the new definition before the line containing "Happy publishing" awk -v insert="define('WP_DEBUG_DISPLAY', $DEBUG_DISPLAY);\ndefine('WP_DEBUG_LOG', $DEBUG_LOG);" \ ' /Happy publishing/ { @@ -1847,6 +1941,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # Delete old definition + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # Generate insert content + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # Insert before “Happy publishing” + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1856,7 +1987,7 @@ nginx_br() { fi if [ "$mode" == "on" ]; then - # Turn on Brotli: Remove comments + # Turn on Brotli: remove comments sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1870,7 +2001,7 @@ nginx_br() { sed -i '/brotli_types/,+6 s/^\(\s*\)#\s*/\1/' /home/web/nginx.conf elif [ "$mode" == "off" ]; then - # Close Brotli: Add comments + # Close Brotli: add comments sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1886,11 +2017,11 @@ nginx_br() { }' /home/web/nginx.conf else - echo "Invalid parameter: Use 'on' or 'off'" + echo "Invalid argument: use 'on' or 'off'" return 1 fi - # Check nginx images and handle them according to the situation + # Check the nginx image and handle it accordingly if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1912,7 +2043,7 @@ nginx_zstd() { fi if [ "$mode" == "on" ]; then - # Turn on Zstd: Remove comments + # Turn on Zstd: remove comments sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1927,7 +2058,7 @@ nginx_zstd() { elif [ "$mode" == "off" ]; then - # Close Zstd: Add comments + # Close Zstd: add comments sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1943,11 +2074,11 @@ nginx_zstd() { else - echo "Invalid parameter: Use 'on' or 'off'" + echo "Invalid argument: use 'on' or 'off'" return 1 fi - # Check nginx images and handle them according to the situation + # Check the nginx image and handle it accordingly if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1974,7 +2105,7 @@ nginx_gzip() { elif [ "$mode" == "off" ]; then sed -i 's|^\(\s*\)gzip on;|\1# gzip on;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "Invalid parameter: Use 'on' or 'off'" + echo "Invalid argument: use 'on' or 'off'" return 1 fi @@ -1990,45 +2121,42 @@ nginx_gzip() { web_security() { send_stats "LDNMP environment defense" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "Server website defense program${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "Server website defense program${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" - echo "1. Install the defense program" + echo "1. Install a defense program" echo "------------------------" - echo "5. View SSH interception record 6. View website interception record" - echo "7. View the list of defense rules 8. View real-time monitoring of logs" + echo "5. View SSH interception records 6. View website interception records" + echo "7. View the list of defense rules 8. View logs for real-time monitoring" echo "------------------------" - echo "11. Configure intercept parameters 12. Clear all blocked IPs" + echo "11. Configure interception parameters 12. Clear all blocked IPs" echo "------------------------" - echo "21. cloudflare mode 22. High load on 5 seconds shield" + echo "21. cloudflare mode 22. Enable 5 seconds shield under high load" echo "------------------------" echo "31. Turn on WAF 32. Turn off WAF" - echo "33. Turn on DDOS Defense 34. Turn off DDOS Defense" + echo "33. Turn on DDOS defense 34. Turn off DDOS defense" echo "------------------------" echo "9. Uninstall the defense program" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,93 +2170,94 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null echo "Fail2Ban defense program has been uninstalled" + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) send_stats "cloudflare mode" - echo "Go to the upper right corner of the cf background, select the API token on the left, and obtain the Global API Key" + echo "Go to my profile in the upper right corner of the cf backend, select the API token on the left, and get the Global API Key" echo "https://dash.cloudflare.com/login" - read -e -p "Enter CF account number:" cfuser - read -e -p "Enter the Global API Key for CF:" cftoken + read -e -p "Enter CF’s account number:" cfuser + read -e -p "Enter CF’s Global API Key:" cftoken wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status - echo "Cloudflare mode is configured to view intercept records in the cf background, site-security-events" + echo "Cloudflare mode has been configured, and the interception record can be viewed in the cf background, site-security-events" ;; 22) - send_stats "High load on 5 seconds shield" - echo -e "${gl_huang}The website automatically detects every 5 minutes. When high load is detected, the shield will be automatically turned on, and low load will be automatically turned off for 5 seconds.${gl_bai}" + send_stats "High load enables 5 seconds shield" + echo -e "${gl_huang}The website automatically detects every 5 minutes. When it detects high load, it will automatically open the shield, and when it detects low load, it will automatically close the shield for 5 seconds.${gl_bai}" echo "--------------" echo "Get CF parameters:" - echo -e "Go to the upper right corner of the cf background, select the API token on the left, and obtain it${gl_huang}Global API Key${gl_bai}" - echo -e "Go to the bottom right of the cf background domain name summary page to get${gl_huang}Region ID${gl_bai}" + echo -e "Go to my profile in the upper right corner of the cf backend, select the API token on the left, and get${gl_huang}Global API Key${gl_bai}" + echo -e "Go to the bottom right of the cf backend domain name summary page to get it${gl_huang}Area ID${gl_bai}" echo "https://dash.cloudflare.com/login" echo "--------------" - read -e -p "Enter CF account number:" cfuser - read -e -p "Enter the Global API Key for CF:" cftoken - read -e -p "Enter the region ID of the domain name in CF:" cfzonID + read -e -p "Enter CF’s account number:" cfuser + read -e -p "Enter CF’s Global API Key:" cftoken + read -e -p "Enter the zone ID of the domain name in CF:" cfzonID cd ~ install jq bc @@ -2147,7 +2276,7 @@ web_security() { (crontab -l 2>/dev/null; echo "$cron_job") | crontab - echo "High load automatic shield opening script has been added" else - echo "Automatic shield script already exists, no need to add it" + echo "The automatic shield opening script already exists, no need to add it" fi ;; @@ -2160,8 +2289,8 @@ web_security() { 32) nginx_waf off - echo "Site WAF has been closed" - send_stats "Site WAF has been closed" + echo "Site WAF is down" + send_stats "Site WAF is down" ;; 33) @@ -2176,26 +2305,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { +check_ldnmp_mode() { -CONFIG_FILE="/home/web/nginx.conf" + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# Get the current worker_processes setting value -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') - -# Set mode information according to value -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # Check if MySQL configuration file contains 4096M + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info="High performance mode" + else + mode_info="Standard mode" + fi @@ -2204,25 +2330,25 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" - # Check whether zstd is enabled and not commented (the whole line starts with zstd on;) + # Check whether zstd is on and uncommented (the whole line starts with zstd on;) if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then - zstd_status=" zstd压缩已开启" + zstd_status="zstd compression is on" else zstd_status="" fi - # Check if brotli is enabled and not commented + # Check if brotli is enabled and uncommented if grep -qE '^\s*brotli\s+on;' "$CONFIG_FILE"; then - br_status=" br压缩已开启" + br_status="brCompression is on" else br_status="" fi - # Check if gzip is enabled and not commented + # Check if gzip is enabled and uncommented if grep -qE '^\s*gzip\s+on;' "$CONFIG_FILE"; then - gzip_status=" gzip压缩已开启" + gzip_status="gzip compression is on" else gzip_status="" fi @@ -2233,13 +2359,13 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear send_stats "Optimize LDNMP environment" echo -e "Optimize LDNMP environment${gl_lv}${mode_info}${gzip_status}${br_status}${zstd_status}${gl_bai}" echo "------------------------" - echo "1. Standard mode 2. High performance mode (recommended 2H4G or above)" + echo "1. Standard mode 2. High performance mode (2H4G or above recommended)" echo "------------------------" echo "3. Turn on gzip compression 4. Turn off gzip compression" echo "5. Turn on br compression 6. Turn off br compression" @@ -2247,14 +2373,16 @@ web_optimization() { echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Site standard mode" + send_stats "site standards mode" + + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf - # nginx tuning - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf # php tuning wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2282,19 +2410,20 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced - echo "LDNMP environment has been set to standard mode" + echo "The LDNMP environment has been set to standard mode" ;; 2) send_stats "Site high performance mode" # nginx tuning - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf # php tuning wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2321,10 +2450,9 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_web_server - echo "LDNMP environment has been set to high performance mode" + echo "The LDNMP environment has been set to high performance mode" ;; 3) @@ -2371,23 +2499,30 @@ web_optimization() { +check_docker_app() { + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then + check_docker="${gl_lv}Installed${gl_bai}" + else + check_docker="${gl_hui}Not installed${gl_bai}" + fi +} -check_docker_app() { +# check_docker_app() { -if docker inspect "$docker_name" &>/dev/null; then - check_docker="${gl_lv}已安装${gl_bai}" -else - check_docker="${gl_hui}未安装${gl_bai}" -fi +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then +# check_docker="${gl_lv} has installed ${gl_bai}" +# else +# check_docker="${gl_hui} is not installed ${gl_bai}" +# fi -} +# } check_docker_app_ip() { echo "------------------------" -echo "Access address:" +echo "Visit address:" ip_address @@ -2416,54 +2551,61 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. Regional inspection + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # Get the container creation time and image name + # 2. Get local mirror information local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) - - # Extract mirror warehouses and tags - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} - - # The default label is latest - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ -z "$container_info" ]] && return - # Add support for official images - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. Intelligent routing judgment + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- Scenario A: Mirror on GitHub (ghcr.io) --- + # Extract the warehouse path, for example ghcr.io/onexru/oneimg -> onexru/oneimg + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # Note: The API of ghcr.io is relatively complex. Usually the fastest way is to check the Release of GitHub Repo + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- Scenario B: Special designation (even in Docker Hub, I want to judge by GitHub Release) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # Get image publishing time from Docker Hub API - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- Scenario C: Standard Docker Hub --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # Verify the time of acquisition - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # Compare timestamps - if [[ $container_created_ts -lt $last_updated_ts ]]; then - update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" + # 4. Timestamp comparison + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then + update_status="${gl_huang}New version found!${gl_bai}" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 @@ -2488,7 +2630,7 @@ block_container_port() { iptables -I DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # Check and release the local network 127.0.0.0/8 + # Check and allow local network 127.0.0.0/8 if ! iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2505,7 +2647,7 @@ block_container_port() { iptables -I DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # Check and release the local network 127.0.0.0/8 + # Check and allow local network 127.0.0.0/8 if ! iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2515,7 +2657,7 @@ block_container_port() { fi - echo "IP+ ports have been blocked from accessing the service" + echo "IP+port has been blocked from accessing the service" save_iptables_rules } @@ -2541,12 +2683,12 @@ clear_container_rules() { iptables -D DOCKER-USER -p tcp -d "$container_ip" -j DROP fi - # Clear the rules for releasing the specified IP + # Clear the rules that allow specified IPs if iptables -C DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # Clear the rules for release local network 127.0.0.0/8 + # Clear the rules that allow local network 127.0.0.0/8 if iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2560,12 +2702,12 @@ clear_container_rules() { iptables -D DOCKER-USER -p udp -d "$container_ip" -j DROP fi - # Clear the rules for releasing the specified IP + # Clear the rules that allow specified IPs if iptables -C DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # Clear the rules for release local network 127.0.0.0/8 + # Clear the rules that allow local network 127.0.0.0/8 if iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2576,7 +2718,7 @@ clear_container_rules() { fi - echo "IP+ports have been allowed to access the service" + echo "IP+port has been allowed to access the service" save_iptables_rules } @@ -2590,20 +2732,20 @@ block_host_port() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "Error: Please provide the port number and the IP that is allowed to access." - echo "Usage: block_host_port " + echo "Error: Please provide port number and IP to allow access." + echo "Usage: block_host_port " return 1 fi install iptables - # Denied all other IP access + # Deny access from all other IPs if ! iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -j DROP fi - # Allow specified IP access + # Allow access to specified IP if ! iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi @@ -2617,12 +2759,12 @@ block_host_port() { - # Denied all other IP access + # Deny access from all other IPs if ! iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -j DROP fi - # Allow specified IP access + # Allow access to specified IP if ! iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi @@ -2637,7 +2779,7 @@ block_host_port() { iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT fi - echo "IP+ ports have been blocked from accessing the service" + echo "IP+port has been blocked from accessing the service" save_iptables_rules } @@ -2649,47 +2791,47 @@ clear_host_port_rules() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "Error: Please provide the port number and the IP that is allowed to access." - echo "Usage: clear_host_port_rules " + echo "Error: Please provide port number and IP to allow access." + echo "Usage: clear_host_port_rules " return 1 fi install iptables - # Clear rules that block all other IP access + # Clear the rule that blocks access from all other IPs if iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -j DROP fi - # Clear rules that allow native access + # Clear rules that allow local access if iptables -C INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # Clear rules that allow specified IP access + # Clear rules that allow access from specified IPs if iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # Clear rules that block all other IP access + # Clear the rule that blocks access from all other IPs if iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -j DROP fi - # Clear rules that allow native access + # Clear rules that allow local access if iptables -C INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # Clear rules that allow specified IP access + # Clear rules that allow access from specified IPs if iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - echo "IP+ports have been allowed to access the service" + echo "IP+port has been allowed to access the service" save_iptables_rules } @@ -2698,16 +2840,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2720,7 +2879,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2734,26 +2893,28 @@ while true; do echo "1. Install 2. Update 3. Uninstall" echo "------------------------" echo "5. Add domain name access 6. Delete domain name access" - echo "7. Allow IP+ port access 8. Block IP+ port access" + echo "7. Allow IP+port access 8. Block IP+port access" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) - check_disk_space $app_size - read -e -p "Enter the application external service port, and enter the default${docker_port}port:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "Enter the application external service port and press Enter to use it by default.${docker_port}port:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + add_app_id + clear - echo "$docker_nameInstalled" + echo "$docker_nameInstallation completed" check_docker_app_ip echo "" $docker_use @@ -2764,8 +2925,11 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum + + add_app_id + clear - echo "$docker_nameInstalled" + echo "$docker_nameInstallation completed" check_docker_app_ip echo "" $docker_use @@ -2777,20 +2941,22 @@ while true; do docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf - echo "The app has been uninstalled" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "App has been uninstalled" send_stats "uninstall$docker_name" ;; 5) - echo "${docker_name}Domain access settings" - send_stats "${docker_name}Domain access settings" + echo "${docker_name}Domain name access settings" + send_stats "${docker_name}Domain name access settings" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" ;; 6) - echo "Domain name format example.com does not come with https://" + echo "Domain name format example.com without https://" web_del ;; @@ -2817,7 +2983,6 @@ done - docker_app_plus() { send_stats "$app_name" while true; do @@ -2827,7 +2992,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2841,39 +3006,51 @@ docker_app_plus() { echo "1. Install 2. Update 3. Uninstall" echo "------------------------" echo "5. Add domain name access 6. Delete domain name access" - echo "7. Allow IP+ port access 8. Block IP+ port access" + echo "7. Allow IP+port access 8. Block IP+port access" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) - check_disk_space $app_size - read -e -p "Enter the application external service port, and enter the default${docker_port}port:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "Enter the application external service port and press Enter to use it by default.${docker_port}port:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + + add_app_id + send_stats "$app_nameInstall" ;; + 2) docker_app_update + add_app_id + send_stats "$app_namerenew" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_nameuninstall" ;; + 5) - echo "${docker_name}Domain access settings" - send_stats "${docker_name}Domain access settings" + echo "${docker_name}Domain name access settings" + send_stats "${docker_name}Domain name access settings" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) - echo "Domain name format example.com does not come with https://" + echo "Domain name format example.com without https://" web_del ;; 7) @@ -2920,7 +3097,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2929,7 +3106,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2939,7 +3116,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -2966,12 +3143,12 @@ tmux_run_d() { local base_name="tmuxd" local tmuxd_ID=1 -# Functions that check whether the session exists +# Function to check if session exists session_exists() { tmux has-session -t $1 2>/dev/null } -# Loop until a non-existent session name is found +# Loop until a non-existing session name is found while session_exists "$base_name-$tmuxd_ID"; do local tmuxd_ID=$((tmuxd_ID + 1)) done @@ -2985,52 +3162,41 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx +} + +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}Installed${gl_bai}" + else + check_f2b_status="${gl_hui}Not installed${gl_bai}" + fi } f2b_install_sshd() { - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf - else + fi + + if command -v apt &>/dev/null; then install rsyslog systemctl start rsyslog systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog fi - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } f2b_sshd() { @@ -3099,7 +3265,7 @@ ldnmp_install_status_one() { if docker inspect "php" &>/dev/null; then clear send_stats "Unable to install LDNMP environment again" - echo -e "${gl_huang}hint:${gl_bai}The website construction environment is installed. No need to install again!" + echo -e "${gl_huang}hint:${gl_bai}The website building environment has been installed. No need to install again!" break_end linux_ldnmp fi @@ -3112,9 +3278,8 @@ cd ~ send_stats "Install LDNMP environment" root_use clear -echo -e "${gl_huang}The LDNMP environment is not installed, start installing the LDNMP environment...${gl_bai}" -check_disk_space 3 -check_port +echo -e "${gl_huang}The LDNMP environment is not installed. Start installing the LDNMP environment...${gl_bai}" +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3130,8 +3295,7 @@ send_stats "Install nginx environment" root_use clear echo -e "${gl_huang}nginx is not installed, start installing nginx environment...${gl_bai}" -check_disk_space 1 -check_port +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3173,7 +3337,7 @@ nginx_install_status() { ldnmp_web_on() { clear - echo "Yours$webnameBuilt!" + echo "your$webnameIt's built!" echo "https://$yuming" echo "------------------------" echo "$webnameThe installation information is as follows:" @@ -3181,10 +3345,21 @@ ldnmp_web_on() { } nginx_web_on() { - clear - echo "Yours$webnameBuilt!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + echo "your$webnameIt's built!" + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3201,43 +3376,41 @@ ldnmp_wp() { fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# echo "Database name: $dbname" -# echo "Username: $dbuse" -# echo "Password: $dbusepasswd" -# echo "Database address: mysql" -# echo "Table prefix: wp_" } + ldnmp_Proxy() { clear - webname="反向代理-IP+端口" + webname="Reverse proxy-IP+port" yuming="${1:-}" reverseproxy="${2:-}" port="${3:-}" @@ -3247,21 +3420,43 @@ ldnmp_Proxy() { if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "Please enter your anti-generation IP:" reverseproxy + read -e -p "Please enter your anti-generation IP (press Enter to default to the local IP 127.0.0.1):" reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then read -e -p "Please enter your anti-generation port:" port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# dynamically add/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3271,9 +3466,7 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear - webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" + webname="Reverse proxy-load balancing" send_stats "Install$webname" echo "Start deployment$webname" @@ -3281,31 +3474,35 @@ ldnmp_Proxy_backend() { add_yuming fi - # Get multiple IPs entered by the user: ports (separated by spaces) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then - read -e -p "Please enter your multiple anti-generation IP+ ports separated by spaces (for example, 127.0.0.1:3000 127.0.0.1:3002):" reverseproxy_port + read -e -p "Please enter your multiple anti-generation IP+ports separated by spaces (for example, 127.0.0.1:3000 127.0.0.1:3002):" reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # Dynamically generate upstream configuration upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # Replace placeholders in templates - sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i "s/# dynamically add/$upstream_servers/g" /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" nginx_http_on docker exec nginx nginx -s reload @@ -3314,6 +3511,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "Service name" "Communication type" "Local address" "Backend address" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # Service name takes file name + service_name=$(basename "$conf" .conf) + + # Get the server backend IP:port in the upstream block + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # Get listen port + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # Default local IP + ip_address + local_ip="$ipv4_address" + + # Get the communication type, first judging from the file name suffix or content + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # Splice listening IP:port + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "Stream four-layer proxy" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "Stream four-layer proxy forwarding tool$check_docker $update_status" + echo "NGINX Stream is the TCP/UDP proxy module of NGINX, which is used to achieve high-performance transport layer traffic forwarding and load balancing." + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. Install 2. Update 3. Uninstall" + echo "------------------------" + echo "4. Add forwarding service 5. Modify forwarding service 6. Delete forwarding service" + echo "------------------------" + echo "0. Return to the previous menu" + echo "------------------------" + read -e -p "Enter your selection:" choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "Install Stream four-layer agent" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "Update Stream four-layer proxy" + ;; + 3) + read -e -p "Are you sure you want to delete the nginx container? This may affect website functionality! (y/N):" confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "Update Stream four-layer proxy" + echo "nginx container has been deleted." + else + echo "The operation has been cancelled." + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "Add layer 4 proxy" + ;; + 5) + send_stats "Edit forwarding configuration" + read -e -p "Please enter the service name you want to edit:" stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "Modify layer 4 proxy" + ;; + 6) + send_stats "Delete forwarding configuration" + read -e -p "Please enter the service name you want to delete:" stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "Delete layer 4 proxy" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="Stream four-layer proxy-load balancing" + + send_stats "Install$webname" + echo "Start deployment$webname" + + # Get agent name + read -rp "Please enter a proxy forwarding name (e.g. mysql_proxy):" proxy_name + if [ -z "$proxy_name" ]; then + echo "Name cannot be empty"; return 1 + fi + + # Get listening port + read -rp "Please enter the local listening port (such as 3306):" listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "Port must be numeric"; return 1 + fi + + echo "Please select agreement type:" + echo "1. TCP 2. UDP" + read -rp "Please enter the serial number [1-2]:" proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "Invalid selection"; return 1 ;; + esac + + read -e -p "Please enter one or more of your backend IP+ports separated by spaces (for example, 10.13.0.2:3306 10.13.0.3:3306):" reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# dynamically add/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "your$webnameIt's built!" + echo "------------------------" + echo "Visit address:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3331,11 +3722,11 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear send_stats "LDNMP site management" @@ -3343,8 +3734,7 @@ ldnmp_web_status() { echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output}Certificate expiration time" + echo -e "Site:${output}Certificate expiration time" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3355,62 +3745,77 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "database:${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" echo "------------------------" echo "" - echo "Site Directory" + echo "site directory" echo "------------------------" echo -e "data${gl_hui}/home/web/html${gl_bai}Certificate${gl_hui}/home/web/certs${gl_bai}Configuration${gl_hui}/home/web/conf.d${gl_bai}" echo "------------------------" echo "" echo "operate" echo "------------------------" - echo "1. Apply for/update the domain name certificate 2. Change the site domain name" - echo "3. Clean up the site cache 4. Create an associated site" - echo "5. View access log 6. View error log" + echo "1. Apply/update domain name certificate 2. Clone site domain name" + echo "3. Clear site cache 4. Create associated site" + echo "5. View the access log 6. View the error log" echo "7. Edit global configuration 8. Edit site configuration" - echo "9. Manage site database 10. View site analysis report" + echo "9. Manage site database 10. View site analysis reports" echo "------------------------" - echo "20. Delete the specified site data" + echo "20. Delete specified site data" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) send_stats "Apply for a domain name certificate" read -e -p "Please enter your domain name:" yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "Change the site domain name" - echo -e "${gl_hong}Highly recommended:${gl_bai}First back up the entire site data and then change the site domain name!" + send_stats "Clone site domain name" read -e -p "Please enter the old domain name:" oddyuming - read -e -p "Please enter the new domain name:" yuming + read -e -p "Please enter new domain name:" yuming install_certbot install_ssltls certs_status - # mysql replacement - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3421,18 +3826,15 @@ ldnmp_web_status() { done # Website directory replacement - mv /home/web/html/$oddyuming /home/web/html/$yuming + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3441,10 +3843,10 @@ ldnmp_web_status() { web_cache ;; 4) - send_stats "Create an associated site" - echo -e "Associate a new domain name for the existing site for access" - read -e -p "Please enter the existing domain name:" oddyuming - read -e -p "Please enter the new domain name:" yuming + send_stats "Create associated sites" + echo -e "Associate a new domain name with the existing site for access" + read -e -p "Please enter an existing domain name:" oddyuming + read -e -p "Please enter new domain name:" yuming install_certbot install_ssltls certs_status @@ -3476,7 +3878,7 @@ ldnmp_web_status() { 8) send_stats "Edit site configuration" - read -e -p "To edit the site configuration, please enter the domain name you want to edit:" yuming + read -e -p "To edit site configuration, please enter the domain name you want to edit:" yuming install nano nano /home/web/conf.d/$yuming.conf docker exec nginx nginx -s reload @@ -3493,7 +3895,7 @@ ldnmp_web_status() { 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3508,7 +3910,7 @@ ldnmp_web_status() { check_panel_app() { if $lujing > /dev/null 2>&1; then - check_panel="${gl_lv}已安装${gl_bai}" + check_panel="${gl_lv}Installed${gl_bai}" else check_panel="" fi @@ -3522,31 +3924,37 @@ while true; do clear check_panel_app echo -e "$panelname $check_panel" - echo "${panelname}It is a popular and powerful operation and maintenance management panel nowadays." + echo "${panelname}It is a popular and powerful operation and maintenance management panel." echo "Official website introduction:$panelurl " echo "" echo "------------------------" - echo "1. Install 2. Management 3. Uninstall" + echo "1. Install 2. Manage 3. Uninstall" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) check_disk_space 1 install wget iptables_open panel_app_install + + add_app_id send_stats "${panelname}Install" ;; 2) panel_app_manage + + add_app_id send_stats "${panelname}control" ;; 3) panel_app_uninstall + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt send_stats "${panelname}uninstall" ;; *) @@ -3563,9 +3971,9 @@ done check_frp_app() { if [ -d "/home/frp/" ]; then - check_frp="${gl_lv}已安装${gl_bai}" + check_frp="${gl_lv}Installed${gl_bai}" else - check_frp="${gl_hui}未安装${gl_bai}" + check_frp="${gl_hui}Not installed${gl_bai}" fi } @@ -3591,7 +3999,7 @@ donlond_frp() { generate_frps_config() { - send_stats "Install the frp server" + send_stats "Install frp server" # Generate random ports and credentials local bind_port=8055 local dashboard_port=8056 @@ -3613,7 +4021,7 @@ EOF donlond_frp frps - # Output generated information + # Output the generated information ip_address echo "------------------------" echo "Parameters required for client deployment" @@ -3633,7 +4041,7 @@ EOF configure_frpc() { - send_stats "Install the frp client" + send_stats "Install frp client" read -e -p "Please enter the external network docking IP:" server_addr read -e -p "Please enter the external network docking token:" token echo @@ -3655,12 +4063,12 @@ EOF } add_forwarding_service() { - send_stats "Add FRP intranet service" - # Prompt the user to enter the service name and forwarding information - read -e -p "Please enter the service name:" service_name - read -e -p "Please enter the forwarding type (tcp/udp) [Enter default tcp]:" service_type + send_stats "Add frp intranet service" + # Prompts user for service name and forwarding information + read -e -p "Please enter service name:" service_name + read -e -p "Please enter the forwarding type (tcp/udp) [Enter to default to tcp]:" service_type local service_type=${service_type:-tcp} - read -e -p "Please enter the intranet IP [Enter default 127.0.0.1]:" local_ip + read -e -p "Please enter the intranet IP [default is 127.0.0.1 when pressing Enter]:" local_ip local local_ip=${local_ip:-127.0.0.1} read -e -p "Please enter the intranet port:" local_port read -e -p "Please enter the external network port:" remote_port @@ -3675,8 +4083,8 @@ remote_port = ${remote_port} EOF - # Output generated information - echo "Serve$service_nameAdded successfully to frpc.toml" + # Output the generated information + echo "Serve$service_nameSuccessfully added to frpc.toml" docker restart frpc @@ -3687,12 +4095,12 @@ EOF delete_forwarding_service() { - send_stats "Delete the frp intranet service" - # Prompt the user to enter the service name that needs to be deleted - read -e -p "Please enter the service name that needs to be deleted:" service_name - # Use sed to delete the service and its related configurations + send_stats "Delete frp intranet service" + # Prompt the user to enter the name of the service that needs to be deleted + read -e -p "Please enter the service name to be deleted:" service_name + # Use sed to delete the service and its related configuration sed -i "/\[$service_name\]/,/^$/d" /home/frp/frpc.toml - echo "Serve$service_nameDeleted successfully from frpc.toml" + echo "Serve$service_nameSuccessfully removed from frpc.toml" docker restart frpc @@ -3702,8 +4110,8 @@ delete_forwarding_service() { list_forwarding_services() { local config_file="$1" - # Print the header - printf "%-20s %-25s %-30s %-10s\n" "服务名称" "内网地址" "外网地址" "协议" + # Print header + printf "%-20s %-25s %-30s %-10s\n" "Service name" "Intranet address" "External network address" "protocol" awk ' BEGIN { @@ -3723,7 +4131,7 @@ list_forwarding_services() { } /^\[.*\]/ { - # If there is service information, print the current service before processing the new service + # If service information already exists, print the current service before processing the new service if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3732,11 +4140,11 @@ list_forwarding_services() { type } - # Update the current service name + # Update current service name if ($1 != "[common]") { gsub(/[\[\]]/, "", $1) current_service=$1 - # Clear the previous value + # Clear previous value local_ip="" local_port="" remote_port="" @@ -3765,7 +4173,7 @@ list_forwarding_services() { } END { - # Print the information for the last service + # Print information about the last service if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3778,17 +4186,17 @@ list_forwarding_services() { -# Get the FRP server port +# Get FRP server port get_frp_ports() { mapfile -t ports < <(ss -tulnape | grep frps | awk '{print $5}' | awk -F':' '{print $NF}' | sort -u) } # Generate access address generate_access_urls() { - # Get all ports first + # First get all ports get_frp_ports - # Check if there are ports other than 8055/8056 + # Check if there is a port other than 8055/8056 local has_valid_ports=false for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3797,18 +4205,18 @@ generate_access_urls() { fi done - # Show title and content only when there is a valid port + # Show title and content only if there is a valid port if [ "$has_valid_ports" = true ]; then echo "FRP service external access address:" - # Process IPv4 address + # Handling IPv4 addresses for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then echo "http://${ipv4_address}:${port}" fi done - # Process IPv6 addresses (if present) + # Handle IPv6 address if present if [ -n "$ipv6_address" ]; then for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3817,7 +4225,7 @@ generate_access_urls() { done fi - # Handling HTTPS configuration + # Handle HTTPS configuration for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then local frps_search_pattern="${ipv4_address}:${port}" @@ -3845,6 +4253,7 @@ frps_main_ports() { frps_panel() { send_stats "FRP server" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3852,9 +4261,9 @@ frps_panel() { check_frp_app check_docker_image_update $docker_name echo -e "FRP server$check_frp $update_status" - echo "Build an FRP intranet penetration service environment to expose devices without public IP to the Internet" + echo "Build an FRP intranet penetration service environment and expose devices without public IP to the Internet" echo "Official website introduction: https://github.com/fatedier/frp/" - echo "Video teaching: https://www.bilibili.com/video/BV1yMw6e2EwL?t=124.0" + echo "Video tutorial: https://www.bilibili.com/video/BV1yMw6e2EwL?t=124.0" if [ -d "/home/frp/" ]; then check_docker_app_ip frps_main_ports @@ -3863,18 +4272,20 @@ frps_panel() { echo "------------------------" echo "1. Install 2. Update 3. Uninstall" echo "------------------------" - echo "5. Domain name access for intranet service 6. Delete domain name access" + echo "5. Intranet service domain name access 6. Delete domain name access" echo "------------------------" - echo "7. Allow IP+ port access 8. Block IP+ port access" + echo "7. Allow IP+port access 8. Block IP+port access" echo "------------------------" echo "00. Refresh service status 0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) install jq grep ss install_docker generate_frps_config + + add_app_id echo "The FRP server has been installed" ;; 2) @@ -3883,6 +4294,8 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps + + add_app_id echo "The FRP server has been updated" ;; 3) @@ -3893,36 +4306,37 @@ frps_panel() { close_port 8055 8056 - echo "The app has been uninstalled" + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "App has been uninstalled" ;; 5) echo "Reverse intranet penetration service into domain name access" - send_stats "FRP access to external domain names" + send_stats "FRP external domain name access" add_yuming read -e -p "Please enter your intranet penetration service port:" frps_port ldnmp_Proxy ${yuming} 127.0.0.1 ${frps_port} block_host_port "$frps_port" "$ipv4_address" ;; 6) - echo "Domain name format example.com does not come with https://" + echo "Domain name format example.com without https://" web_del ;; 7) send_stats "Allow IP access" - read -e -p "Please enter the port to be released:" frps_port + read -e -p "Please enter the port that needs to be released:" frps_port clear_host_port_rules "$frps_port" "$ipv4_address" ;; 8) send_stats "Block IP access" - echo "If you have accessed the anti-generation domain name, you can use this function to block IP+ port access, which is more secure." - read -e -p "Please enter the port you need to block:" frps_port + echo "If you have reversed domain name access, you can use this function to block IP+port access, which is safer." + read -e -p "Please enter the port to be blocked:" frps_port block_host_port "$frps_port" "$ipv4_address" ;; 00) - send_stats "Refresh the FRP service status" + send_stats "Refresh FRP service status" echo "FRP service status has been refreshed" ;; @@ -3936,17 +4350,18 @@ frps_panel() { frpc_panel() { - send_stats "FRP Client" + send_stats "FRP client" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do clear check_frp_app check_docker_image_update $docker_name - echo -e "FRP Client$check_frp $update_status" - echo "Docking with the server, after docking, you can create intranet penetration service to the Internet access" + echo -e "FRP client$check_frp $update_status" + echo "Connect with the server. After the connection, you can create an intranet penetration service to access the Internet." echo "Official website introduction: https://github.com/fatedier/frp/" - echo "Video teaching: https://www.bilibili.com/video/BV1yMw6e2EwL?t=173.9" + echo "Video tutorial: https://www.bilibili.com/video/BV1yMw6e2EwL?t=173.9" echo "------------------------" if [ -d "/home/frp/" ]; then [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml @@ -3956,16 +4371,18 @@ frpc_panel() { echo "------------------------" echo "1. Install 2. Update 3. Uninstall" echo "------------------------" - echo "4. Add external services 5. Delete external services 6. Configure services manually" + echo "4. Add external services 5. Delete external services 6. Manually configure services" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) install jq grep ss install_docker configure_frpc + + add_app_id echo "The FRP client has been installed" ;; 2) @@ -3974,6 +4391,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc + + add_app_id echo "The FRP client has been updated" ;; @@ -3983,7 +4402,9 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 - echo "The app has been uninstalled" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "App has been uninstalled" ;; 4) @@ -4013,6 +4434,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4022,15 +4444,15 @@ yt_menu_pro() { while true; do if [ -x "/usr/local/bin/yt-dlp" ]; then - local YTDLP_STATUS="${gl_lv}已安装${gl_bai}" + local YTDLP_STATUS="${gl_lv}Installed${gl_bai}" else - local YTDLP_STATUS="${gl_hui}未安装${gl_bai}" + local YTDLP_STATUS="${gl_hui}Not installed${gl_bai}" fi clear send_stats "yt-dlp download tool" echo -e "yt-dlp $YTDLP_STATUS" - echo -e "yt-dlp is a powerful video download tool that supports thousands of sites including YouTube, Bilibili, Twitter, etc." + echo -e "yt-dlp is a powerful video download tool that supports thousands of sites such as YouTube, Bilibili, Twitter, etc." echo -e "Official website address: https://github.com/yt-dlp/yt-dlp" echo "-------------------------" echo "Downloaded video list:" @@ -4039,43 +4461,49 @@ yt_menu_pro() { echo "1. Install 2. Update 3. Uninstall" echo "-------------------------" echo "5. Single video download 6. Batch video download 7. Custom parameter download" - echo "8. Download as MP3 audio 9. Delete the video directory 10. Cookie management (under development)" + echo "8. Download as MP3 audio 9. Delete video directory 10. Cookie management (under development)" echo "-------------------------" echo "0. Return to the previous menu" echo "-------------------------" - read -e -p "Please enter the option number:" choice + read -e -p "Please enter option number:" choice case $choice in 1) send_stats "Installing yt-dlp..." echo "Installing yt-dlp..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id echo "The installation is complete. Press any key to continue..." read ;; 2) - send_stats "Update yt-dlp..." - echo "Update yt-dlp..." - sudo yt-dlp -U + send_stats "Updating yt-dlp..." + echo "Updating yt-dlp..." + yt-dlp -U + + add_app_id echo "Update completed. Press any key to continue..." read ;; 3) send_stats "Uninstalling yt-dlp..." echo "Uninstalling yt-dlp..." - sudo rm -f /usr/local/bin/yt-dlp - echo "Uninstall is complete. Press any key to continue..." + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "Uninstallation completed. Press any key to continue..." read ;; 5) send_stats "Single video download" - read -e -p "Please enter the video link:" url + read -e -p "Please enter video link:" url yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "After the download is complete, press any key to continue..." ;; + read -e -p "Download completed, press any key to continue..." ;; 6) send_stats "Batch video download" install nano @@ -4083,7 +4511,7 @@ yt_menu_pro() { echo -e "# Enter multiple video link addresses\n# https://www.bilibili.com/bangumi/play/ep733316?spm_id_from=333.337.0.0&from_spmid=666.25.episode.0" > "$URL_FILE" fi nano $URL_FILE - echo "Now start batch download..." + echo "Start batch download now..." yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ @@ -4091,31 +4519,31 @@ yt_menu_pro() { -a "$URL_FILE" \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "The batch download is completed, press any key to continue..." ;; + read -e -p "Batch download completed, press any key to continue..." ;; 7) send_stats "Custom video download" - read -e -p "Please enter the full yt-dlp parameter (excluding yt-dlp):" custom + read -e -p "Please enter the complete yt-dlp parameters (excluding yt-dlp):" custom yt-dlp -P "$VIDEO_DIR" $custom \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "After the execution is completed, press any key to continue..." ;; + read -e -p "Execution completed, press any key to continue..." ;; 8) send_stats "MP3 download" - read -e -p "Please enter the video link:" url + read -e -p "Please enter video link:" url yt-dlp -P "$VIDEO_DIR" -x --audio-format mp3 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "The audio download is completed, press any key to continue..." ;; + read -e -p "Audio download complete, press any key to continue..." ;; 9) send_stats "Delete video" - read -e -p "Please enter the name of the delete video:" rmdir + read -e -p "Please enter the name of the deleted video:" rmdir rm -rf "$VIDEO_DIR/$rmdir" ;; *) @@ -4151,7 +4579,7 @@ set_timedate() { -# Fix dpkg interrupt problem +# Fix dpkg interruption problem fix_dpkg() { pkill -9 -f 'apt|dpkg' rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock @@ -4160,7 +4588,7 @@ fix_dpkg() { linux_update() { - echo -e "${gl_huang}System update...${gl_bai}" + echo -e "${gl_huang}System update in progress...${gl_bai}" if command -v dnf &>/dev/null; then dnf -y update elif command -v yum &>/dev/null; then @@ -4187,7 +4615,7 @@ linux_update() { linux_clean() { - echo -e "${gl_huang}Cleaning up the system...${gl_bai}" + echo -e "${gl_huang}System cleaning in progress...${gl_bai}" if command -v dnf &>/dev/null; then rpm --rebuilddb dnf autoremove -y @@ -4216,9 +4644,9 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v apk &>/dev/null; then - echo "Clean the package manager cache..." + echo "Clean package manager cache..." apk cache clean - echo "Delete the system log..." + echo "Delete system log..." rm -rf /var/log/* echo "Delete APK cache..." rm -rf /var/cache/apk/* @@ -4240,7 +4668,7 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v opkg &>/dev/null; then - echo "Delete the system log..." + echo "Delete system log..." rm -rf /var/log/* echo "Delete temporary files..." rm -rf /tmp/* @@ -4248,9 +4676,9 @@ linux_clean() { elif command -v pkg &>/dev/null; then echo "Clean up unused dependencies..." pkg autoremove -y - echo "Clean the package manager cache..." + echo "Clean package manager cache..." pkg clean -y - echo "Delete the system log..." + echo "Delete system log..." rm -rf /var/log/* echo "Delete temporary files..." rm -rf /tmp/* @@ -4266,9 +4694,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4278,8 +4705,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4291,6 +4718,13 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } @@ -4315,7 +4749,7 @@ while true; do echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" Limiting + read -e -p "Please enter your choice:" Limiting case "$Limiting" in 1) local dns1_ipv4="1.1.1.1" @@ -4335,7 +4769,9 @@ while true; do ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf + chattr +i /etc/resolv.conf send_stats "Manually edit DNS configuration" ;; *) @@ -4359,7 +4795,7 @@ correct_ssh_config() { local sshd_config="/etc/ssh/sshd_config" - # If PasswordAuthentication is found, set to yes + # If found PasswordAuthentication is set to yes if grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" @@ -4373,7 +4809,7 @@ correct_ssh_config() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' "$sshd_config" fi - # If neither PasswordAuthentication nor PubkeyAuthentication matches, set the default value + # Sets default value if neither PasswordAuthentication nor PubkeyAuthentication matches if ! grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config" && ! grep -Eq "^PubkeyAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" @@ -4384,7 +4820,7 @@ correct_ssh_config() { new_ssh_port() { - # Backup SSH configuration files + # Back up SSH configuration files cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sed -i 's/^\s*#\?\s*Port/Port/' /etc/ssh/sshd_config @@ -4415,7 +4851,7 @@ add_sshkey() { chmod 600 ~/.ssh/authorized_keys ip_address - echo -e "The private key information has been generated. Be sure to copy and save it.${gl_huang}${ipv4_address}_ssh.key${gl_bai}File for future SSH login" + echo -e "The private key information has been generated. Be sure to copy and save it. It can be saved as${gl_huang}${ipv4_address}_ssh.key${gl_bai}file for future SSH logins" echo "--------------------------------" cat ~/.ssh/sshkey @@ -4427,17 +4863,17 @@ add_sshkey() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}ROOT private key login is enabled, ROOT password login has been closed, reconnection will take effect${gl_bai}" + echo -e "${gl_lv}ROOT private key login has been turned on, ROOT password login has been turned off, and reconnection will take effect.${gl_bai}" } import_sshkey() { - read -e -p "Please enter your SSH public key contents (usually starting with 'ssh-rsa' or 'ssh-ed25519'):" public_key + read -e -p "Please enter the contents of your SSH public key (usually starts with 'ssh-rsa' or 'ssh-ed25519'):" public_key if [[ -z "$public_key" ]]; then - echo -e "${gl_hong}Error: The public key content was not entered.${gl_bai}" + echo -e "${gl_hong}Error: Public key content not entered.${gl_bai}" return 1 fi @@ -4455,7 +4891,7 @@ import_sshkey() { rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}The public key has been successfully imported, the ROOT private key login has been enabled, the ROOT password login has been closed, and the reconnection will take effect${gl_bai}" + echo -e "${gl_lv}The public key has been successfully imported, ROOT private key login has been enabled, and ROOT password login has been closed. Reconnection will take effect.${gl_bai}" } @@ -4470,14 +4906,14 @@ sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_confi sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config; rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh -echo -e "${gl_lv}ROOT login is set up!${gl_bai}" +echo -e "${gl_lv}ROOT login setup is completed!${gl_bai}" } root_use() { clear -[ "$EUID" -ne 0 ] && echo -e "${gl_huang}hint:${gl_bai}This feature requires root user to run!" && break_end && kejilion +[ "$EUID" -ne 0 ] && echo -e "${gl_huang}hint:${gl_bai}This function requires root user to run!" && break_end && kejilion } @@ -4495,6 +4931,7 @@ dd_xitong() { dd_xitong_1() { echo -e "Initial username after reinstallation:${gl_huang}root${gl_bai}Initial password:${gl_huang}LeitboGi0ro${gl_bai}Initial port:${gl_huang}22${gl_bai}" + echo -e "${gl_huang}After reinstallation, please change the initial password in time to prevent violent intrusion. Enter passwd on the command line to change the password.${gl_bai}" echo -e "Press any key to continue..." read -n 1 -s -r -p "" install wget @@ -4527,11 +4964,13 @@ dd_xitong() { root_use echo "Reinstall the system" echo "--------------------------------" - echo -e "${gl_hong}Notice:${gl_bai}Reinstallation is risky to lose contact, and those who are worried should use it with caution. Reinstallation is expected to take 15 minutes, please back up the data in advance." - echo -e "${gl_hui}Thanks to MollyLau and bin456789 for the script support!${gl_bai} " + echo -e "${gl_hong}Notice:${gl_bai}Reinstalling may cause loss of connection, so use with caution if you are worried. Reinstallation is expected to take 15 minutes, please back up your data in advance." + echo -e "${gl_hui}Thanks to boss bin456789 and boss leitbogioro for their script support!${gl_bai} " + echo -e "${gl_hui}bin456789 project address: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro project address: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4547,39 +4986,42 @@ dd_xitong() { echo "35. openSUSE Tumbleweed 36. fnos Feiniu public beta version" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please select the system to reinstall:" sys_choice + read -e -p "Please select the system you want to reinstall:" sys_choice case "$sys_choice" in + + 1) - send_stats "Reinstall debian 12" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "Reinstall debian 13" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "Reinstall debian 11" + send_stats "Reinstall debian 12" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "Reinstall debian 10" + send_stats "Reinstall debian 11" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "Reinstall debian 9" + send_stats "Reinstall debian 10" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; @@ -4734,21 +5176,21 @@ dd_xitong() { ;; 36) - send_stats "Reload flying cow" + send_stats "Reinstall Feiniu" dd_xitong_3 bash reinstall.sh fnos reboot exit ;; - 41) - send_stats "Reinstall windows11" + send_stats "Reinstall Windows 11" dd_xitong_2 bash InstallNET.sh -windows 11 -lang "cn" reboot exit ;; + 42) dd_xitong_2 send_stats "Reinstall Windows 10" @@ -4756,8 +5198,9 @@ dd_xitong() { reboot exit ;; + 43) - send_stats "Reinstall Windows 7" + send_stats "Reinstall windows7" dd_xitong_4 bash reinstall.sh windows --iso="https://drive.massgrave.dev/cn_windows_7_professional_with_sp1_x64_dvd_u_677031.iso" --image-name='Windows 7 PROFESSIONAL' reboot @@ -4765,23 +5208,25 @@ dd_xitong() { ;; 44) - send_stats "Reinstall windows server 22" + send_stats "Reinstall windows server 25" dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "Reinstall windows server 19" + send_stats "Reinstall windows server 22" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "Reinstall windows server 16" + send_stats "Reinstall windows server 19" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; @@ -4817,17 +5262,17 @@ bbrv3() { while true; do clear local kernel_version=$(uname -r) - echo "You have installed xanmod's BBRv3 kernel" + echo "You have xanmod's BBRv3 kernel installed" echo "Current kernel version:$kernel_version" echo "" - echo "Kernel Management" + echo "Kernel management" echo "------------------------" - echo "1. Update the BBRv3 kernel 2. Uninstall the BBRv3 kernel" + echo "1. Update BBRv3 kernel 2. Uninstall BBRv3 kernel" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) @@ -4837,7 +5282,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # Step 3: Add a repository + # Step 3: Add repository echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4846,7 +5291,7 @@ bbrv3() { apt update -y apt install -y linux-xanmod-x64v$version - echo "The XanMod kernel has been updated. Take effect after restart" + echo "XanMod kernel has been updated. Take effect after restart" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* @@ -4856,7 +5301,7 @@ bbrv3() { 2) apt purge -y 'linux-*xanmod1*' update-grub - echo "The XanMod kernel is uninstalled. Take effect after restart" + echo "The XanMod kernel has been uninstalled. Take effect after restart" server_reboot ;; @@ -4872,11 +5317,10 @@ bbrv3() { echo "Set up BBR3 acceleration" echo "Video introduction: https://www.bilibili.com/video/BV14K421x7BS?t=0.1" echo "------------------------------------------------" - echo "Only support Debian/Ubuntu" - echo "Please back up the data and will enable BBR3 for you to upgrade the Linux kernel." - echo "VPS has 512M memory, please add 1G virtual memory in advance to prevent missing contact due to insufficient memory!" + echo "Only supports Debian/Ubuntu" + echo "Please back up your data and we will upgrade your Linux kernel and enable BBR3." echo "------------------------------------------------" - read -e -p "Are you sure to continue? (Y/N):" choice + read -e -p "Are you sure you want to continue? (Y/N):" choice case "$choice" in [Yy]) @@ -4884,12 +5328,12 @@ bbrv3() { if [ -r /etc/os-release ]; then . /etc/os-release if [ "$ID" != "debian" ] && [ "$ID" != "ubuntu" ]; then - echo "The current environment does not support it, only supports Debian and Ubuntu systems" + echo "The current environment does not support it. Only Debian and Ubuntu systems are supported." break_end linux_Settings fi else - echo "Unable to determine the operating system type" + echo "Unable to determine operating system type" break_end linux_Settings fi @@ -4900,7 +5344,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # Step 3: Add a repository + # Step 3: Add repository echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4911,7 +5355,7 @@ bbrv3() { bbr_on - echo "XanMod kernel is installed and BBR3 is enabled successfully. Take effect after restart" + echo "The XanMod kernel is installed and BBR3 is enabled successfully. Take effect after restart" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* server_reboot @@ -4930,29 +5374,29 @@ bbrv3() { elrepo_install() { - # Import ELRepo GPG public key + # Import the ELRepo GPG public key echo "Import the ELRepo GPG public key..." rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - # Detect system version + # Check system version local os_version=$(rpm -q --qf "%{VERSION}" $(rpm -qf /etc/os-release) 2>/dev/null | awk -F '.' '{print $1}') local os_name=$(awk -F= '/^NAME/{print $2}' /etc/os-release) - # Make sure we run on a supported operating system + # Make sure we're running on a supported operating system if [[ "$os_name" != *"Red Hat"* && "$os_name" != *"AlmaLinux"* && "$os_name" != *"Rocky"* && "$os_name" != *"Oracle"* && "$os_name" != *"CentOS"* ]]; then echo "Unsupported operating systems:$os_name" break_end linux_Settings fi # Print detected operating system information - echo "Operating system detected:$os_name $os_version" - # 根据系统版本安装对应的 ELRepo 仓库配置 + echo "Detected operating systems:$os_name $os_version" + # Install the corresponding ELRepo warehouse configuration according to the system version if [[ "$os_version" == 8 ]]; then - echo "Install ELRepo repository configuration (version 8)..." + echo "Installing the ELRepo repository configuration (version 8)..." yum -y install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm elif [[ "$os_version" == 9 ]]; then - echo "Install ELRepo repository configuration (version 9)..." + echo "Installing the ELRepo repository configuration (version 9)..." yum -y install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm elif [[ "$os_version" == 10 ]]; then - echo "Install ELRepo repository configuration (version 10)..." + echo "Installing the ELRepo repository configuration (version 10)..." yum -y install https://www.elrepo.org/elrepo-release-10.el10.elrepo.noarch.rpm else echo "Unsupported system versions:$os_version" @@ -4963,7 +5407,7 @@ elrepo_install() { echo "Enable the ELRepo kernel repository and install the latest mainline kernel..." # yum -y --enablerepo=elrepo-kernel install kernel-ml yum --nogpgcheck -y --enablerepo=elrepo-kernel install kernel-ml - echo "The ELRepo repository configuration is installed and updated to the latest mainline kernel." + echo "Installed ELRepo repository configuration and updated to latest mainline kernel." server_reboot } @@ -4976,32 +5420,32 @@ elrepo() { while true; do clear kernel_version=$(uname -r) - echo "You have installed the elrepo kernel" + echo "You have installed elrepo kernel" echo "Current kernel version:$kernel_version" echo "" - echo "Kernel Management" + echo "Kernel management" echo "------------------------" - echo "1. Update the elrepo kernel 2. Uninstall the elrepo kernel" + echo "1. Update elrepo kernel 2. Uninstall elrepo kernel" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps elrepo_install - send_stats "Update the Red Hat kernel" + send_stats "Update Red Hat Kernel" server_reboot ;; 2) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps - echo "The elrepo kernel is uninstalled. Take effect after restart" - send_stats "Uninstall the Red Hat kernel" + echo "The elrepo kernel has been uninstalled. Take effect after restart" + send_stats "Uninstall Red Hat Kernel" server_reboot ;; @@ -5014,19 +5458,19 @@ elrepo() { else clear - echo "Please back up the data and will upgrade the Linux kernel for you" + echo "Please back up your data and we will upgrade the Linux kernel for you." echo "Video introduction: https://www.bilibili.com/video/BV1mH4y1w7qA?t=529.2" echo "------------------------------------------------" - echo "Only support Red Hat series distributions CentOS/RedHat/Alma/Rocky/oracle" - echo "Upgrading the Linux kernel can improve system performance and security. It is recommended to try it if conditions permit and upgrade the production environment with caution!" + echo "Only supports Red Hat series distributions CentOS/RedHat/Alma/Rocky/oracle" + echo "Upgrading the Linux kernel can improve system performance and security. It is recommended to try it if possible, and upgrade the production environment with caution!" echo "------------------------------------------------" - read -e -p "Are you sure to continue? (Y/N):" choice + read -e -p "Are you sure you want to continue? (Y/N):" choice case "$choice" in [Yy]) check_swap elrepo_install - send_stats "Upgrade the Red Hat kernel" + send_stats "Upgrade Red Hat kernel" server_reboot ;; [Nn]) @@ -5044,7 +5488,7 @@ elrepo() { clamav_freshclam() { - echo -e "${gl_huang}Update the virus database...${gl_bai}" + echo -e "${gl_huang}Updating virus database...${gl_bai}" docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ @@ -5054,7 +5498,7 @@ clamav_freshclam() { clamav_scan() { if [ $# -eq 0 ]; then - echo "Please specify the directory to scan." + echo "Please specify the directories to scan." return fi @@ -5075,8 +5519,8 @@ clamav_scan() { mkdir -p /home/docker/clamav/log/ > /dev/null 2>&1 > /home/docker/clamav/log/scan.log > /dev/null 2>&1 - # Execute Docker commands - docker run -it --rm \ + # Execute Docker command + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5084,8 +5528,8 @@ clamav_scan() { clamav/clamav-debian:latest \ clamscan -r --log=/var/log/clamav/scan.log $SCAN_PARAMS - echo -e "${gl_lv}$@ Scan is completed, virus report is stored${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" - echo -e "${gl_lv}If there is a virus, please${gl_huang}scan.log${gl_lv}Search for FOUND keyword in the file to confirm the location of the virus${gl_bai}" + echo -e "${gl_lv}$@ 扫描完成,病毒报告存放在${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" + echo -e "${gl_lv}If there is a virus please${gl_huang}scan.log${gl_lv}Search the file for the FOUND keyword to confirm the location of the virus${gl_bai}" } @@ -5097,23 +5541,23 @@ clamav_scan() { clamav() { root_use - send_stats "Virus Scan Management" + send_stats "Virus scan management" while true; do clear echo "clamav virus scanning tool" echo "Video introduction: https://www.bilibili.com/video/BV1TqvZe4EQm?t=0.1" echo "------------------------" - echo "It is an open source antivirus software tool, mainly used to detect and remove various types of malware." - echo "Including viruses, Trojan horses, spyware, malicious scripts and other harmful software." + echo "It is an open source antivirus software tool mainly used to detect and remove various types of malware." + echo "Includes viruses, Trojan horses, spyware, malicious scripts and other harmful software." echo "------------------------" - echo -e "${gl_lv}1. Full disk scan${gl_bai} ${gl_huang}2. Scan the important directory${gl_bai} ${gl_kjlan}3. Custom directory scanning${gl_bai}" + echo -e "${gl_lv}1. Full scan${gl_bai} ${gl_huang}2. Scan important directories${gl_bai} ${gl_kjlan}3. Custom directory scanning${gl_bai}" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Full disk scan" + send_stats "Full scan" install_docker docker volume create clam_db > /dev/null 2>&1 clamav_freshclam @@ -5130,8 +5574,8 @@ clamav() { break_end ;; 3) - send_stats "Custom directory scanning" - read -e -p "Please enter the directory to scan, separated by spaces (for example: /etc /var /usr /home /root):" directories + send_stats "Custom directory scan" + read -e -p "Please enter the directories to scan, separated by spaces (for example: /etc /var /usr /home /root):" directories install_docker clamav_freshclam clamav_scan $directories @@ -5148,9 +5592,9 @@ clamav() { -# High-performance mode optimization function +# High performance mode optimization function optimize_high_performance() { - echo -e "${gl_lv}Switch to${tiaoyou_moshi}...${gl_bai}" + echo -e "${gl_lv}switch to${tiaoyou_moshi}...${gl_bai}" echo -e "${gl_lv}Optimize file descriptors...${gl_bai}" ulimit -n 65535 @@ -5181,7 +5625,7 @@ optimize_high_performance() { sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null echo -e "${gl_lv}Other optimizations...${gl_bai}" - # Disable large transparent pages to reduce latency + # Disable transparent huge pages to reduce latency echo never > /sys/kernel/mm/transparent_hugepage/enabled # Disable NUMA balancing sysctl -w kernel.numa_balancing=0 2>/dev/null @@ -5189,7 +5633,7 @@ optimize_high_performance() { } -# Equalization mode optimization function +# Balanced mode optimization function optimize_balanced() { echo -e "${gl_lv}Switch to equalization mode...${gl_bai}" @@ -5222,7 +5666,7 @@ optimize_balanced() { sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null echo -e "${gl_lv}Other optimizations...${gl_bai}" - # Restore transparent page + # Restore transparent huge pages echo always > /sys/kernel/mm/transparent_hugepage/enabled # Restore NUMA balancing sysctl -w kernel.numa_balancing=1 2>/dev/null @@ -5230,11 +5674,11 @@ optimize_balanced() { } -# Restore the default settings function +# Restore default settings function restore_defaults() { - echo -e "${gl_lv}Restore to default settings...${gl_bai}" + echo -e "${gl_lv}Revert to default settings...${gl_bai}" - echo -e "${gl_lv}Restore file descriptor...${gl_bai}" + echo -e "${gl_lv}Restore file descriptors...${gl_bai}" ulimit -n 1024 echo -e "${gl_lv}Restore virtual memory...${gl_bai}" @@ -5244,7 +5688,7 @@ restore_defaults() { sysctl -w vm.overcommit_memory=0 2>/dev/null sysctl -w vm.min_free_kbytes=16384 2>/dev/null - echo -e "${gl_lv}Restore network settings...${gl_bai}" + echo -e "${gl_lv}Reset network settings...${gl_bai}" sysctl -w net.core.rmem_max=212992 2>/dev/null sysctl -w net.core.wmem_max=212992 2>/dev/null sysctl -w net.core.netdev_max_backlog=1000 2>/dev/null @@ -5262,8 +5706,8 @@ restore_defaults() { echo -e "${gl_lv}Restore CPU settings...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null - echo -e "${gl_lv}Restore other optimizations...${gl_bai}" - # Restore transparent page + echo -e "${gl_lv}Revert other optimizations...${gl_bai}" + # Restore transparent huge pages echo always > /sys/kernel/mm/transparent_hugepage/enabled # Restore NUMA balancing sysctl -w kernel.numa_balancing=1 2>/dev/null @@ -5274,7 +5718,7 @@ restore_defaults() { # Website building optimization function optimize_web_server() { - echo -e "${gl_lv}Switch to the website building optimization mode...${gl_bai}" + echo -e "${gl_lv}Switch to website construction optimization mode...${gl_bai}" echo -e "${gl_lv}Optimize file descriptors...${gl_bai}" ulimit -n 65535 @@ -5305,7 +5749,7 @@ optimize_web_server() { sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null echo -e "${gl_lv}Other optimizations...${gl_bai}" - # Disable large transparent pages to reduce latency + # Disable transparent huge pages to reduce latency echo never > /sys/kernel/mm/transparent_hugepage/enabled # Disable NUMA balancing sysctl -w kernel.numa_balancing=0 2>/dev/null @@ -5319,27 +5763,27 @@ Kernel_optimize() { while true; do clear send_stats "Linux kernel tuning management" - echo "Optimization of kernel parameters in Linux system" + echo "Linux system kernel parameter optimization" echo "Video introduction: https://www.bilibili.com/video/BV1Kb421J7yg?t=0.1" echo "------------------------------------------------" - echo "A variety of system parameter tuning modes are provided, and users can choose and switch according to their own usage scenarios." - echo -e "${gl_huang}hint:${gl_bai}Please use it with caution in the production environment!" + echo "Provides a variety of system parameter tuning modes, and users can choose to switch according to their own usage scenarios." + echo -e "${gl_huang}hint:${gl_bai}Please use it with caution in production environment!" echo "--------------------" echo "1. High-performance optimization mode: Maximize system performance and optimize file descriptors, virtual memory, network settings, cache management and CPU settings." - echo "2. Balanced optimization mode: Balance between performance and resource consumption, suitable for daily use." - echo "3. Website optimization mode: Optimize for the website server to improve concurrent connection processing capabilities, response speed and overall performance." - echo "4. Live broadcast optimization mode: Optimize the special needs of live broadcast streaming to reduce latency and improve transmission performance." - echo "5. Game server optimization mode: Optimize for game servers to improve concurrent processing capabilities and response speed." - echo "6. Restore the default settings: Restore the system settings to the default configuration." + echo "2. Balanced optimization mode: strikes a balance between performance and resource consumption, suitable for daily use." + echo "3. Website optimization mode: Optimize the website server to improve concurrent connection processing capabilities, response speed and overall performance." + echo "4. Live broadcast optimization mode: Optimize the special needs of live streaming to reduce delays and improve transmission performance." + echo "5. Game server optimization mode: Optimize the game server to improve concurrent processing capabilities and response speed." + echo "6. Restore default settings: Restore system settings to default configuration." echo "--------------------" echo "0. Return to the previous menu" echo "--------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) cd ~ clear - local tiaoyou_moshi="高性能优化模式" + local tiaoyou_moshi="High performance optimization mode" optimize_high_performance send_stats "High performance mode optimization" ;; @@ -5353,19 +5797,19 @@ Kernel_optimize() { cd ~ clear optimize_web_server - send_stats "Website optimization model" + send_stats "Website optimization mode" ;; 4) cd ~ clear - local tiaoyou_moshi="直播优化模式" + local tiaoyou_moshi="Live broadcast optimization mode" optimize_high_performance send_stats "Live streaming optimization" ;; 5) cd ~ clear - local tiaoyou_moshi="游戏服优化模式" + local tiaoyou_moshi="Game server optimization mode" optimize_high_performance send_stats "Game server optimization" ;; @@ -5400,7 +5844,7 @@ update_locale() { locale-gen echo "LANG=${lang}" > /etc/default/locale export LANG=${lang} - echo -e "${gl_lv}The system language has been modified to:$langReconnecting SSH takes effect.${gl_bai}" + echo -e "${gl_lv}The system language has been modified to:$langReconnect to SSH to take effect.${gl_bai}" hash -r break_end @@ -5409,7 +5853,7 @@ update_locale() { install glibc-langpack-zh localectl set-locale LANG=${lang} echo "LANG=${lang}" | tee /etc/locale.conf - echo -e "${gl_lv}The system language has been modified to:$langReconnecting SSH takes effect.${gl_bai}" + echo -e "${gl_lv}The system language has been modified to:$langReconnect to SSH to take effect.${gl_bai}" hash -r break_end ;; @@ -5419,7 +5863,7 @@ update_locale() { ;; esac else - echo "Unsupported systems, system type cannot be recognized." + echo "Unsupported system, system type cannot be identified." break_end fi } @@ -5438,12 +5882,12 @@ while true; do echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) update_locale "en_US.UTF-8" "en_US.UTF-8" - send_stats "Switch to English" + send_stats "switch to english" ;; 2) update_locale "zh_CN.UTF-8" "zh_CN.UTF-8" @@ -5473,7 +5917,7 @@ else echo "${bianse}" >> ~/.profile # source ~/.profile fi -echo -e "${gl_lv}Change is completed. Reconnect SSH to view changes!${gl_bai}" +echo -e "${gl_lv}Change completed. Reconnect to SSH to see the changes!${gl_bai}" hash -r break_end @@ -5499,7 +5943,7 @@ shell_bianse() { echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) @@ -5544,7 +5988,7 @@ shell_bianse() { linux_trash() { root_use - send_stats "System Recycling Station" + send_stats "System Recycle Bin" local bashrc_profile="/root/.bashrc" local TRASH_DIR="$HOME/.local/share/Trash/files" @@ -5553,23 +5997,23 @@ linux_trash() { local trash_status if ! grep -q "trash-put" "$bashrc_profile"; then - trash_status="${gl_hui}未启用${gl_bai}" + trash_status="${gl_hui}Not enabled${gl_bai}" else - trash_status="${gl_lv}已启用${gl_bai}" + trash_status="${gl_lv}Enabled${gl_bai}" fi clear - echo -e "Current recycling bin${trash_status}" - echo -e "After enabling, the files deleted by rm will first enter the recycling bin to prevent the mistaken deletion of important files!" + echo -e "Current recycle bin${trash_status}" + echo -e "After enabling it, files deleted by rm will be put into the recycle bin first to prevent accidental deletion of important files!" echo "------------------------------------------------" - ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "The recycling bin is empty" + ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "Recycle bin is empty" echo "------------------------" - echo "1. Enable the Recycle Bin 2. Close the Recycle Bin" - echo "3. Restore content 4. Clear the recycling bin" + echo "1. Enable Recycle Bin 2. Close Recycle Bin" + echo "3. Restore content 4. Empty Recycle Bin" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) @@ -5577,7 +6021,7 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='trash-put'" >> "$bashrc_profile" source "$bashrc_profile" - echo "The Recycle Bin is enabled and deleted files will be moved to the Recycle Bin." + echo "Recycle Bin is enabled, deleted files will be moved to Recycle Bin." sleep 2 ;; 2) @@ -5585,23 +6029,23 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='rm -i'" >> "$bashrc_profile" source "$bashrc_profile" - echo "The recycling bin is closed and the file will be deleted directly." + echo "The recycle bin is closed and the files will be deleted directly." sleep 2 ;; 3) - read -e -p "Enter the file name to restore:" file_to_restore + read -e -p "Enter the file name to be restored:" file_to_restore if [ -e "$TRASH_DIR/$file_to_restore" ]; then mv "$TRASH_DIR/$file_to_restore" "$HOME/" - echo "$file_to_restoreRestored to the home directory." + echo "$file_to_restoreRestored to home directory." else - echo "The file does not exist." + echo "File does not exist." fi ;; 4) - read -e -p "Confirm to clear the recycling bin? [y/n]:" confirm + read -e -p "Are you sure you want to empty the Recycle Bin? [y/n]:" confirm if [[ "$confirm" == "y" ]]; then trash-empty - echo "The recycling bin has been cleared." + echo "Recycle Bin has been emptied." fi ;; *) @@ -5611,21 +6055,24 @@ linux_trash() { done } +linux_fav() { +send_stats "Command Favorites" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} - -# Create a backup +# Create backup create_backup() { - send_stats "Create a backup" + send_stats "Create backup" local TIMESTAMP=$(date +"%Y%m%d%H%M%S") - # Prompt the user to enter the backup directory - echo "Create a backup example:" - echo "- Backup a single directory: /var/www" - echo "- Backup multiple directories: /etc /home /var/log" - echo "- Direct Enter will use the default directory (/etc /usr /home)" - read -r -p "Please enter the directory to back up (multiple directories are separated by spaces, and if you enter directly, use the default directory):" input + # Prompt user for backup directory + echo "Example of creating a backup:" + echo "- Back up a single directory: /var/www" + echo "- Back up multiple directories: /etc /home /var/log" + echo "- Press Enter to use the default directory (/etc /usr /home)" + read -r -p "Please enter the directory to be backed up (separate multiple directories with spaces, and press Enter to use the default directory):" input - # If the user does not enter a directory, use the default directory + # If the user does not enter a directory, the default directory is used if [ -z "$input" ]; then BACKUP_PATHS=( "/etc" # 配置文件和软件包配置 @@ -5633,7 +6080,7 @@ create_backup() { "/home" # 用户数据 ) else - # Separate the directory entered by the user into an array by spaces + # Separate the directories entered by the user into an array by spaces IFS=' ' read -r -a BACKUP_PATHS <<< "$input" fi @@ -5651,20 +6098,20 @@ create_backup() { # Generate backup file name local BACKUP_NAME="${PREFIX}_$TIMESTAMP.tar.gz" - # Print the directory selected by the user + # Print directory selected by user echo "The backup directory you selected is:" for path in "${BACKUP_PATHS[@]}"; do echo "- $path" done - # Create a backup - echo "Creating a backup$BACKUP_NAME..." + # Create backup + echo "Creating backup$BACKUP_NAME..." install tar tar -czvf "$BACKUP_DIR/$BACKUP_NAME" "${BACKUP_PATHS[@]}" - # Check if the command is successful + # Check if the command was successful if [ $? -eq 0 ]; then - echo "The backup was created successfully:$BACKUP_DIR/$BACKUP_NAME" + echo "Backup created successfully:$BACKUP_DIR/$BACKUP_NAME" else echo "Backup creation failed!" exit 1 @@ -5674,8 +6121,8 @@ create_backup() { # Restore backup restore_backup() { send_stats "Restore backup" - # Select the backup you want to restore - read -e -p "Please enter the backup file name to restore:" BACKUP_NAME + # Select the backup to restore + read -e -p "Please enter the backup file name to be restored:" BACKUP_NAME # Check if the backup file exists if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then @@ -5683,13 +6130,13 @@ restore_backup() { exit 1 fi - echo "Recovering backup$BACKUP_NAME..." + echo "Restoring backup$BACKUP_NAME..." tar -xzvf "$BACKUP_DIR/$BACKUP_NAME" -C / if [ $? -eq 0 ]; then - echo "Backup and restore successfully!" + echo "Backup and restore successful!" else - echo "Backup recovery failed!" + echo "Backup restore failed!" exit 1 fi } @@ -5704,7 +6151,7 @@ list_backups() { delete_backup() { send_stats "Delete backup" - read -e -p "Please enter the backup file name to delete:" BACKUP_NAME + read -e -p "Please enter the backup file name to be deleted:" BACKUP_NAME # Check if the backup file exists if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then @@ -5716,7 +6163,7 @@ delete_backup() { rm -f "$BACKUP_DIR/$BACKUP_NAME" if [ $? -eq 0 ]; then - echo "The backup was deleted successfully!" + echo "Backup deleted successfully!" else echo "Backup deletion failed!" exit 1 @@ -5734,11 +6181,11 @@ linux_backup() { echo "------------------------" list_backups echo "------------------------" - echo "1. Create a backup 2. Restore a backup 3. Delete the backup" + echo "1. Create backup 2. Restore backup 3. Delete backup" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) create_backup ;; 2) restore_backup ;; @@ -5759,48 +6206,48 @@ linux_backup() { # Show connection list list_connections() { - echo "Saved connection:" + echo "Saved connections:" echo "------------------------" cat "$CONFIG_FILE" | awk -F'|' '{print NR " - " $1 " (" $2 ")"}' echo "------------------------" } -# Add a new connection +# Add new connection add_connection() { - send_stats "Add a new connection" - echo "Example to create a new connection:" + send_stats "Add new connection" + echo "Example of creating a new connection:" echo "- Connection name: my_server" echo "- IP address: 192.168.1.100" echo "- Username: root" echo "- Port: 22" echo "------------------------" - read -e -p "Please enter the connection name:" name - read -e -p "Please enter your IP address:" ip - read -e -p "Please enter the username (default: root):" user + read -e -p "Please enter a connection name:" name + read -e -p "Please enter IP address:" ip + read -e -p "Please enter username (default: root):" user local user=${user:-root} # 如果用户未输入,则使用默认值 root read -e -p "Please enter the port number (default: 22):" port local port=${port:-22} # 如果用户未输入,则使用默认值 22 - echo "Please select the authentication method:" + echo "Please select an authentication method:" echo "1. Password" echo "2. Key" - read -e -p "Please enter the selection (1/2):" auth_choice + read -e -p "Please enter your choice (1/2):" auth_choice case $auth_choice in 1) - read -s -p "Please enter your password:" password_or_key + read -s -p "Please enter password:" password_or_key echo # 换行 ;; 2) - echo "Please paste the key content (press press Enter twice after pasting):" + echo "Please paste the key content (press Enter twice after pasting):" local password_or_key="" while IFS= read -r line; do - # If the input is empty and the key content already contains the beginning, the input ends + # If the input is a blank line and the key content already contains the beginning, end the input if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # If it is the first line or the key content has been entered, continue to add + # If it is the first line or you have already started entering the key content, continue adding if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then local password_or_key+="${line}"$'\n' fi @@ -5821,19 +6268,19 @@ add_connection() { esac echo "$name|$ip|$user|$port|$password_or_key" >> "$CONFIG_FILE" - echo "The connection is saved!" + echo "Connection saved!" } -# Delete a connection +# Delete connection delete_connection() { - send_stats "Delete a connection" - read -e -p "Please enter the connection number to delete:" num + send_stats "Delete connection" + read -e -p "Please enter the connection number to be deleted:" num local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "Error: The corresponding connection was not found." + echo "Error: Corresponding connection not found." return fi @@ -5845,7 +6292,7 @@ delete_connection() { fi sed -i "${num}d" "$CONFIG_FILE" - echo "The connection has been deleted!" + echo "Connection deleted!" } # Use connection @@ -5855,7 +6302,7 @@ use_connection() { local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "Error: The corresponding connection was not found." + echo "Error: Corresponding connection not found." return fi @@ -5863,16 +6310,16 @@ use_connection() { echo "Connecting to$name ($ip)..." if [[ -f "$password_or_key" ]]; then - # Connect with a key + # Connect using a key ssh -o StrictHostKeyChecking=no -i "$password_or_key" -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then echo "Connection failed! Please check the following:" echo "1. Is the key file path correct?$password_or_key" - echo "2. Whether the key file permissions are correct (should be 600)." - echo "3. Whether the target server allows login using the key." + echo "2. Are the key file permissions correct (should be 600)." + echo "3. Whether the target server allows login using a key." fi else - # Connect with a password + # Connect using password if ! command -v sshpass &> /dev/null; then echo "Error: sshpass is not installed, please install sshpass first." echo "Installation method:" @@ -5883,7 +6330,7 @@ use_connection() { sshpass -p "$password_or_key" ssh -o StrictHostKeyChecking=no -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then echo "Connection failed! Please check the following:" - echo "1. Whether the username and password are correct." + echo "1. Are the username and password correct?" echo "2. Whether the target server allows password login." echo "3. Whether the SSH service of the target server is running normally." fi @@ -5897,7 +6344,7 @@ ssh_manager() { CONFIG_FILE="$HOME/.ssh_connections" KEY_DIR="$HOME/.ssh/ssh_manager_keys" - # Check if the configuration file and key directory exist, and if it does not exist, create it + # Check if the configuration file and key directory exist, create them if they do not exist if [[ ! -f "$CONFIG_FILE" ]]; then touch "$CONFIG_FILE" fi @@ -5909,15 +6356,15 @@ ssh_manager() { while true; do clear - echo "SSH Remote Connection Tool" - echo "Can be connected to other Linux systems via SSH" + echo "SSH remote connection tool" + echo "Can connect to other Linux systems via SSH" echo "------------------------" list_connections - echo "1. Create a new connection 2. Use a connection 3. Delete a connection" + echo "1. Create a new connection 2. Use the connection 3. Delete the connection" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) add_connection ;; 2) use_connection ;; @@ -5941,14 +6388,14 @@ ssh_manager() { # List available hard disk partitions list_partitions() { - echo "Available hard disk partitions:" + echo "Available hard drive partitions:" lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT | grep -v "sr\|loop" } -# Mount the partition +# Mount partition mount_partition() { - send_stats "Mount the partition" - read -e -p "Please enter the partition name to be mounted (for example, sda1):" PARTITION + send_stats "Mount partition" + read -e -p "Please enter the name of the partition to be mounted (e.g. sda1):" PARTITION # Check if the partition exists if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then @@ -5956,47 +6403,47 @@ mount_partition() { return fi - # Check if the partition is already mounted + # Check whether the partition is mounted if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "The partition is already mounted!" + echo "The partition has been mounted!" return fi - # Create a mount point + # Create mount point MOUNT_POINT="/mnt/$PARTITION" mkdir -p "$MOUNT_POINT" - # Mount the partition + # Mount partition mount "/dev/$PARTITION" "$MOUNT_POINT" if [ $? -eq 0 ]; then - echo "Partition mount successfully:$MOUNT_POINT" + echo "Partition mounted successfully:$MOUNT_POINT" else echo "Partition mount failed!" rmdir "$MOUNT_POINT" fi } -# Uninstall the partition +# Unmount partition unmount_partition() { - send_stats "Uninstall the partition" - read -e -p "Please enter the partition name (for example, sda1):" PARTITION + send_stats "Unmount partition" + read -e -p "Please enter the name of the partition to be unmounted (e.g. sda1):" PARTITION - # Check if the partition is already mounted + # Check whether the partition is mounted MOUNT_POINT=$(lsblk -o MOUNTPOINT | grep -w "$PARTITION") if [ -z "$MOUNT_POINT" ]; then echo "The partition is not mounted!" return fi - # Uninstall the partition + # Unmount partition umount "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "Partition uninstallation successfully:$MOUNT_POINT" + echo "Partition uninstalled successfully:$MOUNT_POINT" rmdir "$MOUNT_POINT" else - echo "Partition uninstallation failed!" + echo "Partition uninstall failed!" fi } @@ -6009,7 +6456,7 @@ list_mounted_partitions() { # Format partition format_partition() { send_stats "Format partition" - read -e -p "Please enter the partition name to format (for example, sda1):" PARTITION + read -e -p "Please enter the name of the partition to be formatted (e.g. sda1):" PARTITION # Check if the partition exists if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then @@ -6017,19 +6464,19 @@ format_partition() { return fi - # Check if the partition is already mounted + # Check whether the partition is mounted if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "The partition has been mounted, please uninstall it first!" + echo "The partition has been mounted, please unmount it first!" return fi - # Select a file system type - echo "Please select the file system type:" + # Select file system type + echo "Please select a file system type:" echo "1. ext4" echo "2. xfs" echo "3. ntfs" echo "4. vfat" - read -e -p "Please enter your selection:" FS_CHOICE + read -e -p "Please enter your choice:" FS_CHOICE case $FS_CHOICE in 1) FS_TYPE="ext4" ;; @@ -6040,7 +6487,7 @@ format_partition() { esac # Confirm formatting - read -e -p "Confirm formatting partition /dev/$PARTITIONfor$FS_TYPEIs it? (y/n):" CONFIRM + read -e -p "Confirm formatted partition /dev/$PARTITIONfor$FS_TYPE? (y/n):" CONFIRM if [ "$CONFIRM" != "y" ]; then echo "The operation has been cancelled." return @@ -6051,7 +6498,7 @@ format_partition() { mkfs.$FS_TYPE "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "The partition format was successful!" + echo "Partition formatted successfully!" else echo "Partition formatting failed!" fi @@ -6069,26 +6516,26 @@ check_partition() { fi # Check partition status - echo "Check partition /dev/$PARTITIONStatus:" + echo "Check partition /dev/$PARTITIONstatus:" fsck "/dev/$PARTITION" } -# Main Menu +# Main menu disk_manager() { send_stats "Hard disk management function" while true; do clear - echo "Hard disk partition management" - echo -e "${gl_huang}This function is internally tested during the test period, please do not use it in the production environment.${gl_bai}" + echo "Hard drive partition management" + echo -e "${gl_huang}This feature is under internal testing and should not be used in a production environment.${gl_bai}" echo "------------------------" list_partitions echo "------------------------" - echo "1. Mount the partition 2. Uninstall the partition 3. View mounted partition" - echo "4. Format the partition 5. Check the partition status" + echo "1. Mount the partition 2. Unmount the partition 3. View the mounted partition" + echo "4. Format partition 5. Check partition status" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) mount_partition ;; 2) unmount_partition ;; @@ -6106,49 +6553,49 @@ disk_manager() { # Show task list list_tasks() { - echo "Saved synchronization tasks:" + echo "Saved sync tasks:" echo "---------------------------------" awk -F'|' '{print NR " - " $1 " ( " $2 " -> " $3":"$4 " )"}' "$CONFIG_FILE" echo "---------------------------------" } -# Add a new task +# Add new task add_task() { - send_stats "Add a new synchronization task" - echo "Create a new synchronization task example:" + send_stats "Add new sync task" + echo "Example of creating a new sync task:" echo "- Task name: backup_www" - echo "- Local Directory: /var/www" + echo "- Local directory: /var/www" echo "- Remote address: user@192.168.1.100" - echo "- Remote Directory: /backup/www" + echo "- Remote directory: /backup/www" echo "- Port number (default 22)" echo "---------------------------------" read -e -p "Please enter the task name:" name read -e -p "Please enter the local directory:" local_path read -e -p "Please enter the remote directory:" remote_path - read -e -p "Please enter the remote user @IP:" remote + read -e -p "Please enter remote user@IP:" remote read -e -p "Please enter the SSH port (default 22):" port port=${port:-22} - echo "Please select the authentication method:" + echo "Please select an authentication method:" echo "1. Password" echo "2. Key" read -e -p "Please select (1/2):" auth_choice case $auth_choice in 1) - read -s -p "Please enter your password:" password_or_key + read -s -p "Please enter password:" password_or_key echo # 换行 auth_method="password" ;; 2) - echo "Please paste the key content (press press Enter twice after pasting):" + echo "Please paste the key content (press Enter twice after pasting):" local password_or_key="" while IFS= read -r line; do - # If the input is empty and the key content already contains the beginning, the input ends + # If the input is a blank line and the key content already contains the beginning, end the input if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # If it is the first line or the key content has been entered, continue to add + # If it is the first line or you have already started entering the key content, continue adding if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then password_or_key+="${line}"$'\n' fi @@ -6172,7 +6619,7 @@ add_task() { ;; esac - echo "Please select the synchronization mode:" + echo "Please select synchronization mode:" echo "1. Standard mode (-avz)" echo "2. Delete the target file (-avz --delete)" read -e -p "Please select (1/2):" mode @@ -6186,13 +6633,13 @@ add_task() { install rsync rsync - echo "Task saved!" + echo "Mission saved!" } -# Delete a task +# Delete task delete_task() { - send_stats "Delete synchronization tasks" - read -e -p "Please enter the task number to delete:" num + send_stats "Delete sync task" + read -e -p "Please enter the task number to be deleted:" num local task=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$task" ]]; then @@ -6208,7 +6655,7 @@ delete_task() { fi sed -i "${num}d" "$CONFIG_FILE" - echo "Task deleted!" + echo "Task has been deleted!" } @@ -6218,7 +6665,7 @@ run_task() { CONFIG_FILE="$HOME/.rsync_tasks" CRON_FILE="$HOME/.rsync_cron" - # Analyze parameters + # Parse parameters local direction="push" # 默认是推送到远端 local num @@ -6229,7 +6676,7 @@ run_task() { num="$1" fi - # If there is no incoming task number, prompt the user to enter + # If no task number is passed in, the user is prompted to enter if [[ -z "$num" ]]; then read -e -p "Please enter the task number to be executed:" num fi @@ -6242,13 +6689,13 @@ run_task() { IFS='|' read -r name local_path remote remote_path port options auth_method password_or_key <<< "$task" - # Adjust source and target path according to synchronization direction + # Adjust source and destination paths based on synchronization direction if [[ "$direction" == "pull" ]]; then - echo "Pulling synchronization to local:$remote:$local_path -> $remote_path" + echo "Pulling and synchronizing to local:$remote:$local_path -> $remote_path" source="$remote:$local_path" destination="$remote_path" else - echo "Push synchronization to the remote end:$local_path -> $remote:$remote_path" + echo "Pushing and synchronizing to the remote end:$local_path -> $remote:$remote_path" source="$local_path" destination="$remote:$remote_path" fi @@ -6268,12 +6715,12 @@ run_task() { else # Check whether the key file exists and whether the permissions are correct if [[ ! -f "$password_or_key" ]]; then - echo "Error: The key file does not exist:$password_or_key" + echo "Error: Key file does not exist:$password_or_key" return fi if [[ "$(stat -c %a "$password_or_key")" != "600" ]]; then - echo "Warning: The key file permissions are incorrect, and are being repaired..." + echo "Warning: Incorrect key file permissions, fixing..." chmod 600 "$password_or_key" fi @@ -6281,20 +6728,20 @@ run_task() { fi if [[ $? -eq 0 ]]; then - echo "Synchronization is complete!" + echo "Synchronization completed!" else - echo "Synchronization failed! Please check the following:" + echo "Sync failed! Please check the following:" echo "1. Is the network connection normal?" - echo "2. Is the remote host accessible?" + echo "2. Whether the remote host is accessible" echo "3. Is the authentication information correct?" - echo "4. Do local and remote directories have correct access permissions" + echo "4. Do the local and remote directories have correct access permissions?" fi } -# Create a timed task +# Create a scheduled task schedule_task() { - send_stats "Add synchronization timing tasks" + send_stats "Add synchronization scheduled tasks" read -e -p "Please enter the task number to be synchronized regularly:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then @@ -6302,9 +6749,9 @@ schedule_task() { return fi - echo "Please select the timed execution interval:" - echo "1) Execute once an hour" - echo "2) Perform once a day" + echo "Please select the scheduled execution interval:" + echo "1) Execute once every hour" + echo "2) Execute once a day" echo "3) Execute once a week" read -e -p "Please enter options (1/2/3):" interval @@ -6314,7 +6761,7 @@ schedule_task() { 1) cron_time="$random_minute * * * *" ;; # 每小时,随机分钟执行 2) cron_time="$random_minute 0 * * *" ;; # 每天,随机分钟执行 3) cron_time="$random_minute 0 * * 1" ;; # 每周,随机分钟执行 - *) echo "Error: Please enter a valid option!" ; return ;; + *) echo "Error: Please enter valid options!" ; return ;; esac local cron_job="$cron_time k rsync_run $num" @@ -6322,38 +6769,38 @@ schedule_task() { # Check if the same task already exists if crontab -l | grep -q "k rsync_run $num"; then - echo "Error: The timing synchronization of this task already exists!" + echo "Error: The scheduled synchronization for this task already exists!" return fi - # Create a crontab to the user + # Create to user's crontab (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "The timing task has been created:$cron_job" + echo "Scheduled task has been created:$cron_job" } # View scheduled tasks view_tasks() { - echo "Current timing tasks:" + echo "Current scheduled tasks:" echo "---------------------------------" crontab -l | grep "k rsync_run" echo "---------------------------------" } -# Delete timing tasks +# Delete scheduled tasks delete_task_schedule() { - send_stats "Delete synchronization timing tasks" - read -e -p "Please enter the task number to delete:" num + send_stats "Delete synchronization scheduled tasks" + read -e -p "Please enter the task number to be deleted:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then echo "Error: Please enter a valid task number!" return fi crontab -l | grep -v "k rsync_run $num" | crontab - - echo "Deleted task number$numTiming tasks" + echo "Task number deleted$numscheduled tasks" } -# Task Management Main Menu +# Task management main menu rsync_manager() { CONFIG_FILE="$HOME/.rsync_tasks" CRON_FILE="$HOME/.rsync_cron" @@ -6361,19 +6808,19 @@ rsync_manager() { while true; do clear echo "Rsync remote synchronization tool" - echo "Synchronization between remote directories supports incremental synchronization, efficient and stable." + echo "Synchronization between remote directories supports incremental synchronization, which is efficient and stable." echo "---------------------------------" list_tasks echo view_tasks echo echo "1. Create a new task 2. Delete a task" - echo "3. Perform local synchronization to the remote end 4. Perform remote synchronization to the local end" - echo "5. Create a timing task 6. Delete a timing task" + echo "3. Perform local synchronization to the remote site 4. Perform remote synchronization to the local site" + echo "5. Create a scheduled task 6. Delete a scheduled task" echo "---------------------------------" echo "0. Return to the previous menu" echo "---------------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case $choice in 1) add_task ;; 2) delete_task ;; @@ -6396,7 +6843,7 @@ rsync_manager() { -linux_ps() { +linux_info() { clear send_stats "System information query" @@ -6443,15 +6890,18 @@ linux_ps() { local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1 % 3600) / 60); if (run_days > 0) printf("%d天 ", run_days); if (run_hours > 0) printf("%d时 ", run_hours); printf("%d分\n", run_minutes)}') + local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1% 3600) / 60); if (run_days > 0) printf("%d day ", run_days); if (run_hours > 0) printf("%d hour ", run_hours); printf("%d minute\n", run_minutes)}') local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" echo -e "System information query" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}Host Name:${gl_bai}$hostname" + echo -e "${gl_kjlan}Hostname:${gl_bai}$hostname" echo -e "${gl_kjlan}System version:${gl_bai}$os_info" echo -e "${gl_kjlan}Linux version:${gl_bai}$kernel_version" echo -e "${gl_kjlan}-------------" @@ -6460,14 +6910,15 @@ linux_ps() { echo -e "${gl_kjlan}Number of CPU cores:${gl_bai}$cpu_cores" echo -e "${gl_kjlan}CPU frequency:${gl_bai}$cpu_freq" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU occupancy:${gl_bai}$cpu_usage_percent%" + echo -e "${gl_kjlan}CPU usage:${gl_bai}$cpu_usage_percent%" echo -e "${gl_kjlan}System load:${gl_bai}$load" + echo -e "${gl_kjlan}Number of TCP|UDP connections:${gl_bai}$tcp_count|$udp_count" echo -e "${gl_kjlan}Physical memory:${gl_bai}$mem_info" echo -e "${gl_kjlan}Virtual memory:${gl_bai}$swap_info" - echo -e "${gl_kjlan}Hard disk occupation:${gl_bai}$disk_info" + echo -e "${gl_kjlan}Hard drive usage:${gl_bai}$disk_info" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}Total Receive:${gl_bai}$rx" - echo -e "${gl_kjlan}Total send:${gl_bai}$tx" + echo -e "${gl_kjlan}Total received:${gl_bai}$rx" + echo -e "${gl_kjlan}Total sent:${gl_bai}$tx" echo -e "${gl_kjlan}-------------" echo -e "${gl_kjlan}Network algorithm:${gl_bai}$congestion_algorithm $queue_algorithm" echo -e "${gl_kjlan}-------------" @@ -6480,10 +6931,10 @@ linux_ps() { echo -e "${gl_kjlan}IPv6 address:${gl_bai}$ipv6_address" fi echo -e "${gl_kjlan}DNS address:${gl_bai}$dns_addresses" - echo -e "${gl_kjlan}Geographical location:${gl_bai}$country $city" + echo -e "${gl_kjlan}Location:${gl_bai}$country $city" echo -e "${gl_kjlan}System time:${gl_bai}$timezone $current_time" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}Runtime:${gl_bai}$runtime" + echo -e "${gl_kjlan}Running time:${gl_bai}$runtime" echo @@ -6496,39 +6947,39 @@ linux_tools() { while true; do clear - # send_stats "Basic Tools" - echo -e "Basic tools" + # send_stats "Basic tools" + echo -e "basic tools" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}1. ${gl_bai}curl download tool${gl_huang}★${gl_bai} ${gl_kjlan}2. ${gl_bai}wget download tool${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}3. ${gl_bai}sudo super management permission tool${gl_kjlan}4. ${gl_bai}socat communication connection tool" + echo -e "${gl_kjlan}3. ${gl_bai}sudo super administrative privilege tool${gl_kjlan}4. ${gl_bai}socat communication connection tool" echo -e "${gl_kjlan}5. ${gl_bai}htop system monitoring tool${gl_kjlan}6. ${gl_bai}iftop network traffic monitoring tool" - echo -e "${gl_kjlan}7. ${gl_bai}unzip ZIP compression decompression tool${gl_kjlan}8. ${gl_bai}tar GZ compression decompression tool" + echo -e "${gl_kjlan}7. ${gl_bai}unzip ZIP compression and decompression tool${gl_kjlan}8. ${gl_bai}tar GZ compression and decompression tool" echo -e "${gl_kjlan}9. ${gl_bai}tmux multi-channel background running tool${gl_kjlan}10. ${gl_bai}ffmpeg video encoding live streaming tool" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}btop modern monitoring tools${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}range file management tool" - echo -e "${gl_kjlan}13. ${gl_bai}ncdu disk occupation viewing tool${gl_kjlan}14. ${gl_bai}fzf global search tool" + echo -e "${gl_kjlan}11. ${gl_bai}btop modern monitoring tool${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}ranger file management tool" + echo -e "${gl_kjlan}13. ${gl_bai}ncdu disk usage viewing tool${gl_kjlan}14. ${gl_bai}fzf global search tool" echo -e "${gl_kjlan}15. ${gl_bai}vim text editor${gl_kjlan}16. ${gl_bai}nano text editor${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}git version control system" + echo -e "${gl_kjlan}17. ${gl_bai}git version control system${gl_kjlan}18. ${gl_bai}opencode AI programming assistant${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}The Matrix Screen Guarantee${gl_kjlan}22. ${gl_bai}Train screen security" - echo -e "${gl_kjlan}26. ${gl_bai}Tetris game${gl_kjlan}27. ${gl_bai}Snake-eating game" - echo -e "${gl_kjlan}28. ${gl_bai}Space Invader Game" + echo -e "${gl_kjlan}21. ${gl_bai}The Matrix Screensaver${gl_kjlan}22. ${gl_bai}Running train screensaver" + echo -e "${gl_kjlan}26. ${gl_bai}Tetris mini game${gl_kjlan}27. ${gl_bai}Snake mini game" + echo -e "${gl_kjlan}28. ${gl_bai}space invaders mini game" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}Install all${gl_kjlan}32. ${gl_bai}All installations (excluding screen savers and games)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}31. ${gl_bai}Install all${gl_kjlan}32. ${gl_bai}Install all (excluding screensavers and games)${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}33. ${gl_bai}Uninstall all" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}Install the specified tool${gl_kjlan}42. ${gl_bai}Uninstall the specified tool" + echo -e "${gl_kjlan}41. ${gl_bai}Install specified tools${gl_kjlan}42. ${gl_bai}Uninstall the specified tool" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) clear install curl clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" curl --help send_stats "Install curl" ;; @@ -6536,7 +6987,7 @@ linux_tools() { clear install wget clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" wget --help send_stats "Install wget" ;; @@ -6544,15 +6995,15 @@ linux_tools() { clear install sudo clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" sudo --help - send_stats "Install sudo" + send_stats "install sudo" ;; 4) clear install socat clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" socat -h send_stats "Install socat" ;; @@ -6574,15 +7025,15 @@ linux_tools() { clear install unzip clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" unzip - send_stats "Install unzip" + send_stats "installunzip" ;; 8) clear install tar clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" tar --help send_stats "Install tar" ;; @@ -6590,7 +7041,7 @@ linux_tools() { clear install tmux clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" tmux --help send_stats "Install tmux" ;; @@ -6598,7 +7049,7 @@ linux_tools() { clear install ffmpeg clear - echo "The tool has been installed and the usage method is as follows:" + echo "The tool has been installed and is used as follows:" ffmpeg --help send_stats "Install ffmpeg" ;; @@ -6667,6 +7118,17 @@ linux_tools() { send_stats "Install git" ;; + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "Install opencode" + ;; + + 21) clear install cmatrix @@ -6695,6 +7157,7 @@ linux_tools() { nsnake send_stats "Install nsnake" ;; + 28) clear install ninvaders @@ -6711,7 +7174,7 @@ linux_tools() { 32) clear - send_stats "Install all (excluding games and screen savers)" + send_stats "Install all (excluding games and screensavers)" install curl wget sudo socat htop iftop unzip tar tmux ffmpeg btop ranger ncdu fzf vim nano git ;; @@ -6720,19 +7183,21 @@ linux_tools() { clear send_stats "Uninstall all" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) clear read -e -p "Please enter the installed tool name (wget curl sudo htop):" installname install $installname - send_stats "Install the specified software" + send_stats "Install specified software" ;; 42) clear read -e -p "Please enter the uninstalled tool name (htop ufw tmux cmatrix):" removename remove $removename - send_stats "Uninstall the specified software" + send_stats "Uninstall specified software" ;; 0) @@ -6763,21 +7228,21 @@ linux_bbr() { echo "Current TCP blocking algorithm:$congestion_algorithm $queue_algorithm" echo "" - echo "BBR Management" + echo "BBR management" echo "------------------------" - echo "1. Turn on BBRv3 2. Turn off BBRv3 (restarts)" + echo "1. Turn on BBRv3 2. Turn off BBRv3 (it will restart)" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) bbr_on - send_stats "Alpine enable bbr3" + send_stats "alpine opens bbr3" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6801,52 +7266,380 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # send_stats "docker management" - echo -e "Docker Management" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Install and update Docker environment${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}View Docker global status${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}Docker container management${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}Docker image management" - echo -e "${gl_kjlan}5. ${gl_bai}Docker Network Management" - echo -e "${gl_kjlan}6. ${gl_bai}Docker volume management" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}7. ${gl_bai}Clean useless docker containers and mirror network data volumes" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}8. ${gl_bai}Replace Docker source" - echo -e "${gl_kjlan}9. ${gl_bai}Edit daemon.json file" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}Enable Docker-ipv6 access" - echo -e "${gl_kjlan}12. ${gl_bai}Close Docker-ipv6 access" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}20. ${gl_bai}Uninstall the Docker environment" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' - case $sub_choice in - 1) - clear - send_stats "Install docker environment" - install_add_docker + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } - ;; - 2) - clear + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}Current backup list:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "No backup" + } + + + + # ---------------------------- + # backup + # ---------------------------- + backup_docker() { + send_stats "Docker backup" + + echo -e "${YELLOW}Backing up Docker containers...${NC}" + docker ps --format '{{.Names}}' + read -e -p "Please enter the name of the container to be backed up (separate multiple spaces and press Enter to back up all running containers):" containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}Container not found${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# Automatically generated restore script" >> "$RESTORE_SCRIPT" + + # Record the packaged Compose project path to avoid repeated packaging + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}Backup container:$c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}detected$cis a docker-compose container${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "The compose directory is not detected, please enter the path manually:" project_dir + fi + + # If the Compose project has already been packaged, skip + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}Compose project [$project_name] Already backed up, skip repeated packaging...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose restore:$project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}Compose project [$project_name] Packaged:${project_dir}${NC}" + else + echo -e "${RED}docker-compose.yml not found, skipping this container...${NC}" + fi + else + # Ordinary container backup volume + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "Packing volume:$path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # port + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # environment variables + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # volume mapping + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # mirror + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# Restore container:$c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # Back up all files under /home/docker (excluding subdirectories) + if [ -d "/home/docker" ]; then + echo -e "${BLUE}Back up files under /home/docker...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}Files under /home/docker have been packaged to:${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}Backup completed:${BACKUP_DIR}${NC}" + echo -e "${GREEN}Available restore scripts:${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # reduction + # ---------------------------- + restore_docker() { + + send_stats "Docker restore" + read -e -p "Please enter the backup directory to be restored:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}The backup directory does not exist${NC}"; return; } + + echo -e "${BLUE}Starting the restore operation...${NC}" + + install tar jq gzip + install_docker + + # --------- Prioritize restoring Compose projects --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "Original path not found, please enter the restore directory path:" original_path + + # Check whether the container of the compose project is already running + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}Compose project [$project_name] Containers are already running, skip restore...${NC}" + continue + fi + + read -e -p "Confirm to restore Compose project [$project_name] to path [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "Please enter a new restore path:" original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}Compose project [$project_name] has been extracted to:$original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}Compose project [$project_name] Restore completed!${NC}" + fi + done + + # --------- Continue to restore normal containers --------- + echo -e "${BLUE}Check and restore normal Docker containers...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}Processing container:$container${NC}" + + # Check if the container already exists and is running + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}container [$container] already running, skipping restore...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}Mirror information not found, skip:$container${NC}"; continue; } + + # port mapping + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # environment variables + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # Volume mapping + volume data recovery + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "Recover volume data:$VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # Delete existing but not running containers + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}container [$container] exists but is not running, delete the old container...${NC}" + docker rm -f "$container" + fi + + # Start container + echo "Execute the restore command: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}No backup information for common containers found${NC}" + + # Restore files under /home/docker + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}Restoring files under /home/docker...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}Files under /home/docker have been restored${NC}" + else + echo -e "${YELLOW}The backup of the file under /home/docker was not found, skipping...${NC}" + fi + + + } + + + # ---------------------------- + # migrate + # ---------------------------- + migrate_docker() { + send_stats "Docker migration" + install jq + read -e -p "Please enter the backup directory to be migrated:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}The backup directory does not exist${NC}"; return; } + + read -e -p "Target server IP:" TARGET_IP + read -e -p "Target server SSH username:" TARGET_USER + read -e -p "Target server SSH port [default 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}Transferring backup...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # Log in using key + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # Delete backup + # ---------------------------- + delete_backup() { + send_stats "Docker backup file deletion" + read -e -p "Please enter the backup directory to be deleted:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}The backup directory does not exist${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}Deleted backup:${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # Main menu + # ---------------------------- + main_menu() { + send_stats "Docker backup migration restore" + while true; do + clear + echo "------------------------" + echo -e "Docker backup/migration/restore tool" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. Back up docker project" + echo -e "2. Migrate docker project" + echo -e "3. Restore docker project" + echo -e "4. Delete the backup file of the docker project" + echo "------------------------" + echo -e "0. Return to the previous menu" + echo "------------------------" + read -e -p "Please select:" choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}Invalid option${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "docker management" + echo -e "Docker management" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}Install and update the Docker environment${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}View Docker global status${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}Docker container management${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}Docker image management" + echo -e "${gl_kjlan}5. ${gl_bai}Docker network management" + echo -e "${gl_kjlan}6. ${gl_bai}Docker volume management" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}7. ${gl_bai}Clean up useless docker containers and mirror network data volumes" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}8. ${gl_bai}Change Docker source" + echo -e "${gl_kjlan}9. ${gl_bai}Edit daemon.json file" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}11. ${gl_bai}Enable Docker-ipv6 access" + echo -e "${gl_kjlan}12. ${gl_bai}Turn off Docker-ipv6 access" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}Backup/migrate/restore Docker environment" + echo -e "${gl_kjlan}20. ${gl_bai}Uninstall the Docker environment" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "Please enter your choice:" sub_choice + + case $sub_choice in + 1) + clear + send_stats "Install docker environment" + install_add_docker + + ;; + 2) + clear local container_count=$(docker ps -a -q 2>/dev/null | wc -l) local image_count=$(docker images -q 2>/dev/null | wc -l) local network_count=$(docker network ls -q 2>/dev/null | wc -l) local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) - send_stats "Docker global status" + send_stats "docker global status" echo "Docker version" docker -v docker compose version @@ -6858,10 +7651,10 @@ linux_docker() { echo -e "Docker container:${gl_lv}$container_count${gl_bai}" docker ps -a echo "" - echo -e "Docker volume:${gl_lv}$volume_count${gl_bai}" + echo -e "Docker volumes:${gl_lv}$volume_count${gl_bai}" docker volume ls echo "" - echo -e "Docker Network:${gl_lv}$network_count${gl_bai}" + echo -e "Docker network:${gl_lv}$network_count${gl_bai}" docker network ls echo "" @@ -6876,7 +7669,7 @@ linux_docker() { 5) while true; do clear - send_stats "Docker Network Management" + send_stats "Docker network management" echo "Docker network list" echo "------------------------------------------------------------" docker network ls @@ -6884,7 +7677,7 @@ linux_docker() { echo "------------------------------------------------------------" container_ids=$(docker ps -q) - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "Container name" "network name" "IP address" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") @@ -6901,36 +7694,36 @@ linux_docker() { done echo "" - echo "Network operation" + echo "network operations" echo "------------------------" echo "1. Create a network" - echo "2. Join the Internet" + echo "2. Join the network" echo "3. Exit the network" - echo "4. Delete the network" + echo "4. Delete network" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Create a network" - read -e -p "Set a new network name:" dockernetwork + send_stats "Create network" + read -e -p "Set new network name:" dockernetwork docker network create $dockernetwork ;; 2) - send_stats "Join the Internet" - read -e -p "Join the network name:" dockernetwork - read -e -p "Those containers are added to the network (multiple container names are separated by spaces):" dockernames + send_stats "Join the network" + read -e -p "Add network name:" dockernetwork + read -e -p "Which containers join the network (please separate multiple container names with spaces):" dockernames for dockername in $dockernames; do docker network connect $dockernetwork $dockername done ;; 3) - send_stats "Join the Internet" + send_stats "Join the network" read -e -p "Exit network name:" dockernetwork - read -e -p "Those containers exit the network (multiple container names are separated by spaces):" dockernames + read -e -p "Those containers exit the network (please separate multiple container names with spaces):" dockernames for dockername in $dockernames; do docker network disconnect $dockernetwork $dockername @@ -6939,8 +7732,8 @@ linux_docker() { ;; 4) - send_stats "Delete the network" - read -e -p "Please enter the network name to delete:" dockernetwork + send_stats "delete network" + read -e -p "Please enter the network name to be deleted:" dockernetwork docker network rm $dockernetwork ;; @@ -6958,7 +7751,7 @@ linux_docker() { echo "Docker volume list" docker volume ls echo "" - echo "Volume operation" + echo "Volume operations" echo "------------------------" echo "1. Create a new volume" echo "2. Delete the specified volume" @@ -6966,12 +7759,12 @@ linux_docker() { echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Create a new volume" - read -e -p "Set the new volume name:" dockerjuan + send_stats "Create new volume" + read -e -p "Set new volume name:" dockerjuan docker volume create $dockerjuan ;; @@ -7007,7 +7800,7 @@ linux_docker() { ;; 7) clear - send_stats "Docker cleaning" + send_stats "Docker cleanup" read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}将清理无用的镜像容器网络,包括停止的容器,确定清理吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -7033,18 +7826,26 @@ linux_docker() { restart docker ;; + + + 11) clear - send_stats "Docker v6 open" + send_stats "Docker v6 on" docker_ipv6_on ;; 12) clear - send_stats "Docker v6 level" + send_stats "Docker v6 Close" docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear send_stats "Docker uninstall" @@ -7089,35 +7890,36 @@ linux_test() { echo -e "Test script collection" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}IP and unlock status detection" - echo -e "${gl_kjlan}1. ${gl_bai}ChatGPT Unlock Status Detection" + echo -e "${gl_kjlan}1. ${gl_bai}ChatGPT unlock status detection" echo -e "${gl_kjlan}2. ${gl_bai}Region streaming media unlock test" echo -e "${gl_kjlan}3. ${gl_bai}yeahwu streaming media unlock detection" - echo -e "${gl_kjlan}4. ${gl_bai}xykt IP quality physical examination script${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}xykt IP quality check script${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}Network speed measurement" + echo -e "${gl_kjlan}Network line speed test" echo -e "${gl_kjlan}11. ${gl_bai}besttrace three network backhaul delay routing test" - echo -e "${gl_kjlan}12. ${gl_bai}mtr_trace Three-network backhaul line test" - echo -e "${gl_kjlan}13. ${gl_bai}Superspeed three-net speed measurement" + echo -e "${gl_kjlan}12. ${gl_bai}mtr_trace triple network backhaul line test" + echo -e "${gl_kjlan}13. ${gl_bai}Superspeed triple network speed test" echo -e "${gl_kjlan}14. ${gl_bai}nxtrace fast backhaul test script" - echo -e "${gl_kjlan}15. ${gl_bai}nxtrace Specifies IP backhaul test script" - echo -e "${gl_kjlan}16. ${gl_bai}ludashi2020 three-network line test" - echo -e "${gl_kjlan}17. ${gl_bai}i-abc multifunction speed test script" - echo -e "${gl_kjlan}18. ${gl_bai}NetQuality Network Quality Physical Examination Script${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}15. ${gl_bai}nxtrace specifies IP backhaul test script" + echo -e "${gl_kjlan}16. ${gl_bai}ludashi2020 three network line test" + echo -e "${gl_kjlan}17. ${gl_bai}i-abc multi-function speed test script" + echo -e "${gl_kjlan}18. ${gl_bai}NetQuality network quality check script${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}Hardware performance testing" - echo -e "${gl_kjlan}21. ${gl_bai}yabs performance testing" - echo -e "${gl_kjlan}22. ${gl_bai}iicu/gb5 CPU performance test script" + echo -e "${gl_kjlan}21. ${gl_bai}yabs performance test" + echo -e "${gl_kjlan}22. ${gl_bai}icu/gb5 CPU performance test script" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}Comprehensive test" + echo -e "${gl_kjlan}Comprehensive testing" echo -e "${gl_kjlan}31. ${gl_bai}bench performance test" - echo -e "${gl_kjlan}32. ${gl_bai}Spiritysdx Fusion Monster Review${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}32. ${gl_bai}spiritysdx fusion monster evaluation${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}nodequality fusion monster evaluation${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) @@ -7138,25 +7940,25 @@ linux_test() { ;; 4) clear - send_stats "xykt_IP quality physical examination script" + send_stats "xykt_IP quality check script" bash <(curl -Ls IP.Check.Place) ;; 11) clear - send_stats "Besttrace three network backhaul delay routing test" + send_stats "besttrace triple network backhaul delay routing test" install wget wget -qO- git.io/besttrace | bash ;; 12) clear - send_stats "mtr_trace three network return line test" + send_stats "mtr_trace triple network backhaul line test" curl ${gh_proxy}raw.githubusercontent.com/zhucaidan/mtr_trace/main/mtr_trace.sh | bash ;; 13) clear - send_stats "Superspeed three-net speed measurement" + send_stats "Superspeed triple network speed test" bash <(curl -Lso- https://git.io/superspeed_uxh) ;; 14) @@ -7168,7 +7970,7 @@ linux_test() { 15) clear send_stats "nxtrace specifies IP backhaul test script" - echo "List of IPs that can be referenced" + echo "Reference IP list" echo "------------------------" echo "Beijing Telecom: 219.141.136.12" echo "Beijing Unicom: 202.106.50.1" @@ -7177,30 +7979,30 @@ linux_test() { echo "Shanghai Unicom: 210.22.97.1" echo "Shanghai Mobile: 211.136.112.200" echo "Guangzhou Telecom: 58.60.188.222" - echo "Guangzhou Unicom: 210.21.196.6" + echo "Guangzhou China Unicom: 210.21.196.6" echo "Guangzhou Mobile: 120.196.165.24" echo "Chengdu Telecom: 61.139.2.69" - echo "Chengdu Unicom: 119.6.6.6" + echo "Chengdu China Unicom: 119.6.6.6" echo "Chengdu Mobile: 211.137.96.205" echo "Hunan Telecom: 36.111.200.100" echo "Hunan Unicom: 42.48.16.100" echo "Hunan Mobile: 39.134.254.6" echo "------------------------" - read -e -p "Enter a specified IP:" testip + read -e -p "Enter a specific IP:" testip curl nxtrace.org/nt |bash nexttrace $testip ;; 16) clear - send_stats "ludashi2020 three-network line test" + send_stats "ludashi2020 three network line test" curl ${gh_proxy}raw.githubusercontent.com/ludashi2020/backtrace/main/install.sh -sSf | sh ;; 17) clear - send_stats "i-abc multifunction speed test script" + send_stats "i-abc multifunctional speed test script" bash <(curl -sL ${gh_proxy}raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh) ;; @@ -7212,13 +8014,13 @@ linux_test() { 21) clear - send_stats "yabs performance testing" + send_stats "yabs performance test" check_swap curl -sL yabs.sh | bash -s -- -i -5 ;; 22) clear - send_stats "iicu/gb5 CPU performance test script" + send_stats "icu/gb5 CPU performance test script" check_swap bash <(curl -sL bash.icu/gb5) ;; @@ -7229,11 +8031,19 @@ linux_test() { curl -Lso- bench.sh | bash ;; 32) - send_stats "Spiritysdx Fusion Monster Review" + send_stats "spiritysdx fusion monster review" + clear + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "nodequality fusion monster evaluation" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion @@ -7259,48 +8069,48 @@ linux_Oracle() { echo -e "Oracle Cloud Script Collection" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}1. ${gl_bai}Install idle machine active script" - echo -e "${gl_kjlan}2. ${gl_bai}Uninstall idle machine active script" + echo -e "${gl_kjlan}2. ${gl_bai}Uninstall active scripts from idle machines" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}3. ${gl_bai}DD reinstall system script" - echo -e "${gl_kjlan}4. ${gl_bai}Detective R start script" - echo -e "${gl_kjlan}5. ${gl_bai}Turn on ROOT password login mode" + echo -e "${gl_kjlan}4. ${gl_bai}Detective R startup script" + echo -e "${gl_kjlan}5. ${gl_bai}Enable ROOT password login mode" echo -e "${gl_kjlan}6. ${gl_bai}IPV6 recovery tool" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) clear - echo "Active script: CPU occupies 10-20% memory occupies 20%" - read -e -p "Are you sure to install it? (Y/N):" choice + echo "Active script: CPU usage 10-20% Memory usage 20%" + read -e -p "Are you sure you want to install it? (Y/N):" choice case "$choice" in [Yy]) install_docker - # Set default values + # Set default value local DEFAULT_CPU_CORE=1 local DEFAULT_CPU_UTIL="10-20" local DEFAULT_MEM_UTIL=20 local DEFAULT_SPEEDTEST_INTERVAL=120 - # Prompt the user to enter the number of CPU cores and occupancy percentage, and if entered, use the default value. - read -e -p "Please enter the number of CPU cores [default:$DEFAULT_CPU_CORE]: " cpu_core + # Prompts the user to enter the number of CPU cores and occupancy percentage. If the user presses Enter, the default value will be used. + read -e -p "Please enter the number of CPU cores [Default:$DEFAULT_CPU_CORE]: " cpu_core local cpu_core=${cpu_core:-$DEFAULT_CPU_CORE} - read -e -p "Please enter the CPU usage percentage range (for example, 10-20) [Default:$DEFAULT_CPU_UTIL]: " cpu_util + read -e -p "Please enter the CPU usage percentage range (e.g. 10-20) [Default:$DEFAULT_CPU_UTIL]: " cpu_util local cpu_util=${cpu_util:-$DEFAULT_CPU_UTIL} - read -e -p "Please enter the memory usage percentage [default:$DEFAULT_MEM_UTIL]: " mem_util + read -e -p "Please enter the memory usage percentage [Default:$DEFAULT_MEM_UTIL]: " mem_util local mem_util=${mem_util:-$DEFAULT_MEM_UTIL} - read -e -p "Please enter the Speedtest interval time (seconds) [default:$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval + read -e -p "Please enter Speedtest interval time (seconds) [Default:$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} # Run Docker container - docker run -itd --name=lookbusy --restart=always \ + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ @@ -7329,13 +8139,13 @@ linux_Oracle() { clear echo "Reinstall the system" echo "--------------------------------" - echo -e "${gl_hong}Notice:${gl_bai}Reinstallation is risky to lose contact, and those who are worried should use it with caution. Reinstallation is expected to take 15 minutes, please back up the data in advance." - read -e -p "Are you sure to continue? (Y/N):" choice + echo -e "${gl_hong}Notice:${gl_bai}Reinstalling may cause loss of connection, so use with caution if you are worried. Reinstallation is expected to take 15 minutes, please back up your data in advance." + read -e -p "Are you sure you want to continue? (Y/N):" choice case "$choice" in [Yy]) while true; do - read -e -p "Please select the system to reinstall: 1. Debian12 | 2. Ubuntu20.04:" sys_choice + read -e -p "Please select the system you want to reinstall: 1. Debian12 | 2. Ubuntu20.04:" sys_choice case "$sys_choice" in 1) @@ -7352,10 +8162,10 @@ linux_Oracle() { esac done - read -e -p "Please enter your reinstalled password:" vpspasswd + read -e -p "Please enter your password after reinstallation:" vpspasswd install wget bash <(wget --no-check-certificate -qO- "${gh_proxy}raw.githubusercontent.com/MoeClub/Note/master/InstallNET.sh") $xitong -v 64 -p $vpspasswd -port 22 - send_stats "Oracle Cloud Reinstall System Script" + send_stats "Oracle Cloud reinstall system script" ;; [Nn]) echo "Canceled" @@ -7368,7 +8178,8 @@ linux_Oracle() { 4) clear - echo "This feature is in the development stage, so stay tuned!" + send_stats "Detective R startup script" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7378,8 +8189,8 @@ linux_Oracle() { 6) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "This function is provided by the master jhb, thanks to him!" - send_stats "ipv6 fix" + echo "This function is provided by jhb, thank him!" + send_stats "ipv6 repair" ;; 0) kejilion @@ -7398,6 +8209,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7415,20 +8229,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}The environment is installed${gl_bai} $output $db_output" + echo -e "${gl_lv}Environment is installed${gl_bai}Site:$outputdatabase:$db_output" fi fi @@ -7461,26 +8275,26 @@ linux_ldnmp() { ldnmp_tato echo -e "${gl_huang}------------------------" echo -e "${gl_huang}1. ${gl_bai}Install LDNMP environment${gl_huang}★${gl_bai} ${gl_huang}2. ${gl_bai}Install WordPress${gl_huang}★${gl_bai}" - echo -e "${gl_huang}3. ${gl_bai}Install Discuz Forum${gl_huang}4. ${gl_bai}Install the Kadao Cloud Desktop" - echo -e "${gl_huang}5. ${gl_bai}Install Apple CMS Film and Television Station${gl_huang}6. ${gl_bai}Install a Unicorn Digital Card Network" - echo -e "${gl_huang}7. ${gl_bai}Install the flarum forum website${gl_huang}8. ${gl_bai}Install typecho lightweight blog website" - echo -e "${gl_huang}9. ${gl_bai}Install LinkStack Shared Link Platform${gl_huang}20. ${gl_bai}Customize dynamic site" + echo -e "${gl_huang}3. ${gl_bai}Install Discuz Forum${gl_huang}4. ${gl_bai}Install Kedao Cloud Desktop" + echo -e "${gl_huang}5. ${gl_bai}Install Apple CMS Movie and TV Station${gl_huang}6. ${gl_bai}Install Unicorn Digital Card Network" + echo -e "${gl_huang}7. ${gl_bai}Install flarum forum website${gl_huang}8. ${gl_bai}Install typecho lightweight blog website" + echo -e "${gl_huang}9. ${gl_bai}Install LinkStack sharing link platform${gl_huang}20. ${gl_bai}Custom dynamic site" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}21. ${gl_bai}Install nginx only${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}Site redirection" - echo -e "${gl_huang}23. ${gl_bai}Site reverse proxy-IP+port${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}Site reverse proxy - domain name" - echo -e "${gl_huang}25. ${gl_bai}Install Bitwarden password management platform${gl_huang}26. ${gl_bai}Install Halo Blog Website" - echo -e "${gl_huang}27. ${gl_bai}Install AI Painting Prompt Word Generator${gl_huang}28. ${gl_bai}Site reverse proxy-load balancing" - echo -e "${gl_huang}30. ${gl_bai}Customize static site" + echo -e "${gl_huang}21. ${gl_bai}Only install nginx${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}site redirect" + echo -e "${gl_huang}23. ${gl_bai}Site reverse proxy-IP+port${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}Site reverse proxy-domain name" + echo -e "${gl_huang}25. ${gl_bai}Install Bitwarden Password Management Platform${gl_huang}26. ${gl_bai}Install Halo Blog Site" + echo -e "${gl_huang}27. ${gl_bai}Install the AI ​​painting prompt word generator${gl_huang}28. ${gl_bai}Site reverse proxy-load balancing" + echo -e "${gl_huang}29. ${gl_bai}Stream four-layer proxy forwarding${gl_huang}30. ${gl_bai}Custom static site" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}31. ${gl_bai}Site data management${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}Back up the entire site data" - echo -e "${gl_huang}33. ${gl_bai}Timed remote backup${gl_huang}34. ${gl_bai}Restore the entire site data" + echo -e "${gl_huang}31. ${gl_bai}Site data management${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}Back up site-wide data" + echo -e "${gl_huang}33. ${gl_bai}Scheduled remote backup${gl_huang}34. ${gl_bai}Restore whole site data" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}35. ${gl_bai}Protect LDNMP environment${gl_huang}36. ${gl_bai}Optimize LDNMP environment" - echo -e "${gl_huang}37. ${gl_bai}Update LDNMP environment${gl_huang}38. ${gl_bai}Uninstall LDNMP environment" + echo -e "${gl_huang}35. ${gl_bai}Protect LDNMP environments${gl_huang}36. ${gl_bai}Optimize LDNMP environment" + echo -e "${gl_huang}37. ${gl_bai}Update LDNMP environment${gl_huang}38. ${gl_bai}Uninstall the LDNMP environment" echo -e "${gl_huang}------------------------" echo -e "${gl_huang}0. ${gl_bai}Return to main menu" echo -e "${gl_huang}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in @@ -7495,24 +8309,29 @@ linux_ldnmp() { 3) clear # Discuz Forum - webname="Discuz论坛" + webname="Discuz Forum" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7531,19 +8350,22 @@ linux_ldnmp() { 4) clear - # Kedao Cloud Desktop - webname="可道云桌面" + # Kedao cloud desktop + webname="Kedao cloud desktop" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7566,19 +8388,23 @@ linux_ldnmp() { 5) clear - # Apple CMS - webname="苹果CMS" + # AppleCMS + webname="AppleCMS" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7602,26 +8428,30 @@ linux_ldnmp() { echo "password:$dbusepasswd" echo "Database prefix: mac_" echo "------------------------" - echo "Log in to the background address after installation is successful" + echo "After successful installation, log in to the backend address" echo "https://$yuming/vip.php" ;; 6) clear - # One-legged counting card - webname="独脚数卡" + # One-legged number card + webname="One-legged number card" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7640,36 +8470,39 @@ linux_ldnmp() { echo "password:$dbusepasswd" echo "" echo "redis address: redis" - echo "Redis password: Not filled in by default" - echo "Redis port: 6379" + echo "redis password: not filled in by default" + echo "redis port: 6379" echo "" echo "Website url: https://$yuming" - echo "Background login path: /admin" + echo "Backend login path: /admin" echo "------------------------" echo "Username: admin" echo "Password: admin" echo "------------------------" - echo "If red error0 appears in the upper right corner when logging in, please use the following command:" - echo "I am also very angry that the unicorn number card is so troublesome, and there will be such problems!" + echo "If a red error0 appears in the upper right corner when logging in, please use the following command:" + echo "I am also very angry about why the Unicorn Number Card is so troublesome and has such problems!" echo "sed -i 's/ADMIN_HTTPS=false/ADMIN_HTTPS=true/g' /home/web/html/$yuming/dujiaoka/.env" ;; 7) clear - # Flarum Forum - webname="flarum论坛" + # flarum forum + webname="flarum forum" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7690,9 +8523,13 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp @@ -7702,7 +8539,7 @@ linux_ldnmp() { echo "username:$dbuse" echo "password:$dbusepasswd" echo "Table prefix: flarum_" - echo "Administrator information is set by yourself" + echo "Administrator information can be set by oneself" ;; @@ -7715,12 +8552,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7753,13 +8594,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7783,18 +8627,21 @@ linux_ldnmp() { 20) clear - webname="PHP动态站点" + webname="PHP dynamic site" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7804,8 +8651,8 @@ linux_ldnmp() { clear echo -e "[${gl_huang}1/6${gl_bai}] Upload PHP source code" echo "-------------" - echo "Currently, only zip-format source code packages are allowed. Please put the source code packages in /home/web/html/${yuming}In the directory" - read -e -p "You can also enter the download link to remotely download the source code package. Directly press Enter to skip remote download:" url_download + echo "Currently, only source code packages in zip format are allowed to be uploaded. Please put the source code packages in /home/web/html/${yuming}under directory" + read -e -p "You can also enter the download link to download the source code package remotely. Press Enter directly to skip the remote download:" url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -7820,15 +8667,15 @@ linux_ldnmp() { # find "$(realpath .)" -name "index.php" -print find "$(realpath .)" -name "index.php" -print | xargs -I {} dirname {} - read -e -p "Please enter the path of index.php, similar to (/home/web/html/$yuming/wordpress/): " index_lujing + read -e -p "Please enter the path to index.php, similar to (/home/web/html/$yuming/wordpress/): " index_lujing sed -i "s#root /var/www/html/$yuming/#root $index_lujing#g" /home/web/conf.d/$yuming.conf sed -i "s#/home/web/#/var/www/#g" /home/web/conf.d/$yuming.conf clear - echo -e "[${gl_huang}3/6${gl_bai}] Please select the PHP version" + echo -e "[${gl_huang}3/6${gl_bai}] Please select PHP version" echo "-------------" - read -e -p "1. The latest version of php | 2. php7.4:" pho_v + read -e -p "1. php latest version | 2. php7.4:" pho_v case "$pho_v" in 1) sed -i "s#php:9000#php:9000#g" /home/web/conf.d/$yuming.conf @@ -7845,7 +8692,7 @@ linux_ldnmp() { clear - echo -e "[${gl_huang}4/6${gl_bai}] Install the specified extension" + echo -e "[${gl_huang}4/6${gl_bai}] Install specified extension" echo "-------------" echo "Installed extensions" docker exec php php -m @@ -7859,14 +8706,14 @@ linux_ldnmp() { clear echo -e "[${gl_huang}5/6${gl_bai}] Edit site configuration" echo "-------------" - echo "Press any key to continue, and you can set the site configuration in detail, such as pseudo-static contents, etc." + echo "Press any key to continue. You can set the site configuration in detail, such as pseudo-static content." read -n 1 -s -r -p "" install nano nano /home/web/conf.d/$yuming.conf clear - echo -e "[${gl_huang}6/6${gl_bai}] Database Management" + echo -e "[${gl_huang}6/6${gl_bai}] Database management" echo "-------------" read -e -p "1. I build a new site 2. I build an old site and have a database backup:" use_db case $use_db in @@ -7874,8 +8721,8 @@ linux_ldnmp() { echo ;; 2) - echo "The database backup must be a .gz-end compressed package. Please put it in the /home/ directory to support the import of backup data of Pagoda/1panel." - read -e -p "You can also enter the download link to remotely download the backup data. Directly press Enter will skip remote download:" url_download_db + echo "Database backup must be a compressed package ending in .gz. Please put it in the /home/ directory to support the import of Pagoda/1panel backup data." + read -e -p "You can also enter the download link to download the backup data remotely. Press Enter directly to skip the remote download:" url_download_db cd /home/ if [ -n "$url_download_db" ]; then @@ -7885,7 +8732,7 @@ linux_ldnmp() { latest_sql=$(ls -t *.sql | head -n 1) dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname < "/home/$latest_sql" - echo "Database import table data" + echo "Database imported table data" docker exec -i mysql mysql -u root -p"$dbrootpasswd" -e "USE $dbname; SHOW TABLES;" rm -f *.sql echo "Database import completed" @@ -7917,18 +8764,21 @@ linux_ldnmp() { 22) clear - webname="站点重定向" + webname="site redirect" send_stats "Install$webname" echo "Start deployment$webname" add_yuming - read -e -p "Please enter the jump domain name:" reverseproxy + read -e -p "Please enter the redirect domain name:" reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7943,7 +8793,7 @@ linux_ldnmp() { find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ ports have been blocked from accessing the service" + echo "IP+port has been blocked from accessing the service" else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -7953,19 +8803,21 @@ linux_ldnmp() { 24) clear - webname="反向代理-域名" + webname="Reverse proxy-domain name" send_stats "Install$webname" echo "Start deployment$webname" add_yuming echo -e "Domain name format:${gl_huang}google.com${gl_bai}" - read -e -p "Please enter your anti-generation domain name:" fandai_yuming + read -e -p "Please enter your reverse proxy domain name:" fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7981,20 +8833,17 @@ linux_ldnmp() { send_stats "Install$webname" echo "Start deployment$webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8004,30 +8853,28 @@ linux_ldnmp() { send_stats "Install$webname" echo "Start deployment$webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; 27) clear - webname="AI绘画提示词生成器" + webname="AI painting prompt word generator" send_stats "Install$webname" echo "Start deployment$webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8050,19 +8897,25 @@ linux_ldnmp() { ;; - 30) + 29) + stream_panel + ;; + + 30) clear - webname="静态站点" + webname="static site" send_stats "Install$webname" echo "Start deployment$webname" add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8073,8 +8926,8 @@ linux_ldnmp() { clear echo -e "[${gl_huang}1/2${gl_bai}] Upload static source code" echo "-------------" - echo "Currently, only zip-format source code packages are allowed. Please put the source code packages in /home/web/html/${yuming}In the directory" - read -e -p "You can also enter the download link to remotely download the source code package. Directly press Enter to skip remote download:" url_download + echo "Currently, only source code packages in zip format are allowed to be uploaded. Please put the source code packages in /home/web/html/${yuming}under directory" + read -e -p "You can also enter the download link to download the source code package remotely. Press Enter directly to skip the remote download:" url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -8122,11 +8975,13 @@ linux_ldnmp() { while true; do clear - echo "The backup file has been created: /home/$backup_filename" + echo "Backup file created: /home/$backup_filename" read -e -p "Do you want to transfer backup data to a remote server? (Y/N):" choice case "$choice" in [Yy]) read -e -p "Please enter the remote server IP:" remote_ip + read -e -p "Target server SSH port [default 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then echo "Error: Please enter the remote server IP." continue @@ -8135,7 +8990,7 @@ linux_ldnmp() { if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" echo "The file has been transferred to the remote server home directory." else echo "The file to be transferred was not found." @@ -8154,7 +9009,7 @@ linux_ldnmp() { 33) clear - send_stats "Timed remote backup" + send_stats "Scheduled remote backup" read -e -p "Enter the remote server IP:" useip read -e -p "Enter the remote server password:" usepasswd @@ -8167,17 +9022,17 @@ linux_ldnmp() { echo "------------------------" echo "1. Weekly backup 2. Daily backup" - read -e -p "Please enter your selection:" dingshi + read -e -p "Please enter your choice:" dingshi case $dingshi in 1) check_crontab_installed - read -e -p "Select the day of the week for your weekly backup (0-6, 0 represents Sunday):" weekday + read -e -p "Select the day of the week for weekly backup (0-6, 0 represents Sunday):" weekday (crontab -l ; echo "0 0 * * $weekday ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; 2) check_crontab_installed - read -e -p "Select the time for daily backup (hours, 0-23):" hour + read -e -p "Select daily backup time (hour, 0-23):" hour (crontab -l ; echo "0 $hour * * * ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; *) @@ -8196,14 +9051,14 @@ linux_ldnmp() { echo "-------------------------" ls -lt /home/*.gz | awk '{print $NF}' echo "" - read -e -p "Enter to restore the latest backup, enter the backup file name to restore the specified backup, enter 0 to exit:" filename + read -e -p "Press the Enter key to restore the latest backup, enter the backup file name to restore the specified backup, enter 0 to exit:" filename if [ "$filename" == "0" ]; then break_end linux_ldnmp fi - # If the user does not enter the file name, use the latest compressed package + # If the user does not enter a file name, the latest compressed package is used if [ -z "$filename" ]; then local filename=$(ls -t /home/*.tar.gz | head -1) fi @@ -8213,16 +9068,15 @@ linux_ldnmp() { docker compose down > /dev/null 2>&1 rm -rf /home/web > /dev/null 2>&1 - echo -e "${gl_huang}Decompression is being done$filename ...${gl_bai}" + echo -e "${gl_huang}Unzipping$filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot install_ldnmp else - echo "No compression package was found." + echo "No compressed package found." fi ;; @@ -8244,7 +9098,7 @@ linux_ldnmp() { echo "Update LDNMP environment" echo "------------------------" ldnmp_v - echo "Discover new version of components" + echo "New version of component found" echo "------------------------" check_docker_image_update nginx if [ -n "$update_status" ]; then @@ -8270,7 +9124,7 @@ linux_ldnmp() { echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) nginx_upgrade @@ -8279,7 +9133,7 @@ linux_ldnmp() { 2) local ldnmp_pods="mysql" - read -e -p "Please enter${ldnmp_pods}Version number (such as: 8.0 8.3 8.4 9.0) (Enter to get the latest version):" version + read -e -p "Please enter${ldnmp_pods}Version number (such as: 8.0 8.3 8.4 9.0) (press enter to get the latest version):" version local version=${version:-latest} cd /home/web/ @@ -8296,7 +9150,7 @@ linux_ldnmp() { ;; 3) local ldnmp_pods="php" - read -e -p "Please enter${ldnmp_pods}Version number (such as: 7.4 8.0 8.1 8.2 8.3) (Enter to get the latest version):" version + read -e -p "Please enter${ldnmp_pods}Version number (such as: 7.4 8.0 8.1 8.2 8.3) (press enter to get the latest version):" version local version=${version:-8.3} cd /home/web/ cp /home/web/docker-compose.yml /home/web/docker-compose1.yml @@ -8340,7 +9194,6 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis send_stats "renew$ldnmp_pods" echo "renew${ldnmp_pods}Finish" @@ -8349,11 +9202,10 @@ linux_ldnmp() { read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}长时间不更新环境的用户,请慎重更新LDNMP环境,会有数据库更新失败的风险。确定更新LDNMP环境吗?(Y/N): ")" choice case "$choice" in [Yy]) - send_stats "Completely update the LDNMP environment" + send_stats "Complete update of LDNMP environment" cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8375,7 +9227,7 @@ linux_ldnmp() { 38) root_use - send_stats "Uninstall LDNMP environment" + send_stats "Uninstall the LDNMP environment" read -e -p "$(echo -e "${gl_hong}强烈建议:${gl_bai}先备份全部网站数据,再卸载LDNMP环境。确定删除所有网站数据吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -8411,2264 +9263,3901 @@ linux_ldnmp() { linux_panel() { - while true; do +local sub_choice="$1" + +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi + +while true; do + + if [ -z "$sub_choice" ]; then clear - # send_stats "App Market" - echo -e "Application Market" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Official version of Baota Panel${gl_kjlan}2. ${gl_bai}aaPanel International Edition" - echo -e "${gl_kjlan}3. ${gl_bai}1Panel new generation management panel${gl_kjlan}4. ${gl_bai}NginxProxyManager Visual Panel" - echo -e "${gl_kjlan}5. ${gl_bai}OpenList multi-store file list program${gl_kjlan}6. ${gl_bai}Ubuntu Remote Desktop Web Edition" - echo -e "${gl_kjlan}7. ${gl_bai}Nezha Probe VPS Monitoring Panel${gl_kjlan}8. ${gl_bai}QB Offline BT Magnetic Download Panel" - echo -e "${gl_kjlan}9. ${gl_bai}Poste.io mail server program${gl_kjlan}10. ${gl_bai}RocketChat multiplayer online chat system" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}Zendao project management software${gl_kjlan}12. ${gl_bai}Qinglong Panel Timed Task Management Platform" - echo -e "${gl_kjlan}13. ${gl_bai}Cloudreve network disk${gl_huang}★${gl_bai} ${gl_kjlan}14. ${gl_bai}Simple picture bed picture management program" - echo -e "${gl_kjlan}15. ${gl_bai}emby multimedia management system${gl_kjlan}16. ${gl_bai}Speedtest speed test panel" - echo -e "${gl_kjlan}17. ${gl_bai}AdGuardHome Adware${gl_kjlan}18. ${gl_bai}onlyoffice online office OFFICE" - echo -e "${gl_kjlan}19. ${gl_bai}Thunder Pool WAF firewall panel${gl_kjlan}20. ${gl_bai}portainer container management panel" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}VScode web version${gl_kjlan}22. ${gl_bai}UptimeKuma monitoring tool" - echo -e "${gl_kjlan}23. ${gl_bai}Memos web page memo${gl_kjlan}24. ${gl_bai}Webtop Remote Desktop Web Edition${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}25. ${gl_bai}Nextcloud network disk${gl_kjlan}26. ${gl_bai}QD-Today timing task management framework" - echo -e "${gl_kjlan}27. ${gl_bai}Dockge Container Stack Management Panel${gl_kjlan}28. ${gl_bai}LibreSpeed Speed Test Tool" - echo -e "${gl_kjlan}29. ${gl_bai}searxng aggregation search site${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}PhotoPrism Private Album System" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}StirlingPDF tool collection${gl_kjlan}32. ${gl_bai}drawio free online charting software${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}Sun-Panel Navigation Panel${gl_kjlan}34. ${gl_bai}Pingvin-Share file sharing platform" - echo -e "${gl_kjlan}35. ${gl_bai}Minimalist circle of friends${gl_kjlan}36. ${gl_bai}LobeChatAI Chat Aggregation Website" - echo -e "${gl_kjlan}37. ${gl_bai}MyIP Toolbox${gl_huang}★${gl_bai} ${gl_kjlan}38. ${gl_bai}Xiaoya alist family bucket" - echo -e "${gl_kjlan}39. ${gl_bai}Bililive live broadcast recording tool${gl_kjlan}40. ${gl_bai}webssh web version SSH connection tool" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}Mouse Management Panel${gl_kjlan}42. ${gl_bai}Nexte remote connection tool" - echo -e "${gl_kjlan}43. ${gl_bai}RustDesk Remote Desk (Server)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${gl_bai}RustDesk Remote Desk (Relay)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}45. ${gl_bai}Docker acceleration station${gl_kjlan}46. ${gl_bai}GitHub Acceleration Station${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}47. ${gl_bai}Prometheus Monitoring${gl_kjlan}48. ${gl_bai}Prometheus (host monitoring)" - echo -e "${gl_kjlan}49. ${gl_bai}Prometheus (Container Monitoring)${gl_kjlan}50. ${gl_bai}Replenishment monitoring tool" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}51. ${gl_bai}PVE Chicken Panel${gl_kjlan}52. ${gl_bai}DPanel Container Management Panel" - echo -e "${gl_kjlan}53. ${gl_bai}llama3 chat AI model${gl_kjlan}54. ${gl_bai}AMH Host Website Building Management Panel" - echo -e "${gl_kjlan}55. ${gl_bai}FRP intranet penetration (server side)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${gl_bai}FRP intranet penetration (client)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}57. ${gl_bai}Deepseek chat AI big model${gl_kjlan}58. ${gl_bai}Dify big model knowledge base${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}59. ${gl_bai}NewAPI big model asset management${gl_kjlan}60. ${gl_bai}JumpServer open source bastion machine" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}61. ${gl_bai}Online translation server${gl_kjlan}62. ${gl_bai}RAGFlow big model knowledge base" - echo -e "${gl_kjlan}63. ${gl_bai}OpenWebUI self-hosted AI platform${gl_huang}★${gl_bai} ${gl_kjlan}64. ${gl_bai}it-tools toolbox" - echo -e "${gl_kjlan}65. ${gl_bai}n8n Automation Workflow Platform${gl_huang}★${gl_bai} ${gl_kjlan}66. ${gl_bai}yt-dlp video download tool" - echo -e "${gl_kjlan}67. ${gl_bai}ddns-go Dynamic DNS Management Tool${gl_huang}★${gl_bai} ${gl_kjlan}68. ${gl_bai}AllinSSL Certificate Management Platform" - echo -e "${gl_kjlan}69. ${gl_bai}SFTPGo file transfer tool${gl_kjlan}70. ${gl_bai}AstrBot Chat Robot Framework" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}71. ${gl_bai}Navidrome Private Music Server${gl_kjlan}72. ${gl_bai}bitwarden Password Manager${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}73. ${gl_bai}LibreTV Private Film and Television${gl_kjlan}74. ${gl_bai}MoonTV Private Movie" - echo -e "${gl_kjlan}75. ${gl_bai}Melody Music Elf${gl_kjlan}76. ${gl_bai}Online DOS old games" - echo -e "${gl_kjlan}77. ${gl_bai}Thunder offline download tool${gl_kjlan}78. ${gl_bai}PandaWiki Intelligent Document Management System" - echo -e "${gl_kjlan}79. ${gl_bai}Beszel server monitoring" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + echo -e "application market" + echo -e "${gl_kjlan}-------------------------" - case $sub_choice in - 1) + local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" + # Set color with loop + for i in {1..150}; do + if echo "$app_numbers" | grep -q "^$i$"; then + declare "color$i=${gl_lv}" + else + declare "color$i=${gl_bai}" + fi + done - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } + echo -e "${gl_kjlan}1. ${color1}Pagoda panel official version${gl_kjlan}2. ${color2}aaPanel Pagoda International Version" + echo -e "${gl_kjlan}3. ${color3}1Panel new generation management panel${gl_kjlan}4. ${color4}NginxProxyManager visualization panel" + echo -e "${gl_kjlan}5. ${color5}OpenList multi-store file list program${gl_kjlan}6. ${color6}Ubuntu Remote Desktop Web Edition" + echo -e "${gl_kjlan}7. ${color7}Nezha Probe VPS Monitoring Panel${gl_kjlan}8. ${color8}QB offline BT magnetic download panel" + echo -e "${gl_kjlan}9. ${color9}Poste.io mail server program${gl_kjlan}10. ${color10}RocketChat multi-person online chat system" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}11. ${color11}ZenTao project management software${gl_kjlan}12. ${color12}Qinglong panel scheduled task management platform" + echo -e "${gl_kjlan}13. ${color13}Cloudreve network disk${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}Simple picture bed picture management program" + echo -e "${gl_kjlan}15. ${color15}emby multimedia management system${gl_kjlan}16. ${color16}Speedtest speed test panel" + echo -e "${gl_kjlan}17. ${color17}AdGuardHome removes adware${gl_kjlan}18. ${color18}onlyofficeOnline office OFFICE" + echo -e "${gl_kjlan}19. ${color19}Leichi WAF firewall panel${gl_kjlan}20. ${color20}portainer container management panel" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}21. ${color21}VScode web version${gl_kjlan}22. ${color22}UptimeKuma monitoring tool" + echo -e "${gl_kjlan}23. ${color23}Memos web memo${gl_kjlan}24. ${color24}Webtop remote desktop web version${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}25. ${color25}Nextcloud network disk${gl_kjlan}26. ${color26}QD-Today scheduled task management framework" + echo -e "${gl_kjlan}27. ${color27}Dockge container stack management panel${gl_kjlan}28. ${color28}LibreSpeed ​​speed test tool" + echo -e "${gl_kjlan}29. ${color29}searxng aggregated search station${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrism Private Album System" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}31. ${color31}StirlingPDF Tools Collection${gl_kjlan}32. ${color32}drawio free online charting software${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${color33}Sun-Panel Navigation Panel${gl_kjlan}34. ${color34}Pingvin-Share file sharing platform" + echo -e "${gl_kjlan}35. ${color35}Minimalist circle of friends${gl_kjlan}36. ${color36}LobeChatAI chat aggregation website" + echo -e "${gl_kjlan}37. ${color37}MyIP Toolbox${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}Xiaoya alist family bucket" + echo -e "${gl_kjlan}39. ${color39}Bililive live broadcast recording tool${gl_kjlan}40. ${color40}webssh web version SSH connection tool" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}41. ${color41}Mouse management panel${gl_kjlan}42. ${color42}Nexterm remote connection tool" + echo -e "${gl_kjlan}43. ${color43}RustDesk remote desktop (server)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk remote desktop (relay)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}45. ${color45}Docker acceleration station${gl_kjlan}46. ${color46}GitHub acceleration station${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}47. ${color47}Prometheus monitoring${gl_kjlan}48. ${color48}Prometheus (host monitoring)" + echo -e "${gl_kjlan}49. ${color49}Prometheus (container monitoring)${gl_kjlan}50. ${color50}Replenishment monitoring tools" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}51. ${color51}PVE open chick panel${gl_kjlan}52. ${color52}DPanel container management panel" + echo -e "${gl_kjlan}53. ${color53}llama3 chat AI large model${gl_kjlan}54. ${color54}AMH host website building management panel" + echo -e "${gl_kjlan}55. ${color55}FRP intranet penetration (server)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRP intranet penetration (client)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}57. ${color57}Deepseek chat AI large model${gl_kjlan}58. ${color58}Dify large model knowledge base${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}59. ${color59}NewAPI large model asset management${gl_kjlan}60. ${color60}JumpServer open source bastion machine" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}61. ${color61}Online translation server${gl_kjlan}62. ${color62}RAGFlow large model knowledge base" + echo -e "${gl_kjlan}63. ${color63}OpenWebUI self-hosted AI platform${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}it-tools toolbox" + echo -e "${gl_kjlan}65. ${color65}n8n automated workflow platform${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp video download tool" + echo -e "${gl_kjlan}67. ${color67}ddns-go dynamic DNS management tool${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL certificate management platform" + echo -e "${gl_kjlan}69. ${color69}SFTPGo file transfer tool${gl_kjlan}70. ${color70}AstrBot chatbot framework" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}71. ${color71}Navidrome private music server${gl_kjlan}72. ${color72}bitwarden password manager${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}73. ${color73}LibreTV Private Movies${gl_kjlan}74. ${color74}MoonTV private movies" + echo -e "${gl_kjlan}75. ${color75}Melody music wizard${gl_kjlan}76. ${color76}Online DOS old games" + echo -e "${gl_kjlan}77. ${color77}Thunder offline download tool${gl_kjlan}78. ${color78}PandaWiki intelligent document management system" + echo -e "${gl_kjlan}79. ${color79}Beszel server monitoring${gl_kjlan}80. ${color80}linkwarden bookmark management" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet video conference${gl_kjlan}82. ${color82}gpt-load high-performance AI transparent proxy" + echo -e "${gl_kjlan}83. ${color83}komari server monitoring tool${gl_kjlan}84. ${color84}Wallos personal financial management tool" + echo -e "${gl_kjlan}85. ${color85}immich picture video manager${gl_kjlan}86. ${color86}jellyfin media management system" + echo -e "${gl_kjlan}87. ${color87}SyncTV is a great tool for watching movies together${gl_kjlan}88. ${color88}Owncast self-hosted live streaming platform" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox file express${gl_kjlan}90. ${color90}matrix decentralized chat protocol" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea private code repository${gl_kjlan}92. ${color92}FileBrowser file manager" + echo -e "${gl_kjlan}93. ${color93}Dufs minimalist static file server${gl_kjlan}94. ${color94}Gopeed high-speed download tool" + echo -e "${gl_kjlan}95. ${color95}paperless document management platform${gl_kjlan}96. ${color96}2FAuth self-hosted two-step authenticator" + echo -e "${gl_kjlan}97. ${color97}WireGuard networking (server)${gl_kjlan}98. ${color98}WireGuard networking (client)" + echo -e "${gl_kjlan}99. ${color99}DSM Synology Virtual Machine${gl_kjlan}100. ${color100}Syncthing peer-to-peer file synchronization tool" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI video generation tool${gl_kjlan}102. ${color102}VoceChat multi-person online chat system" + echo -e "${gl_kjlan}103. ${color103}Umami website statistics tool${gl_kjlan}104. ${color104}Stream four-layer proxy forwarding tool" + echo -e "${gl_kjlan}105. ${color105}Siyuan Notes${gl_kjlan}106. ${color106}Drawnix open source whiteboard tool" + echo -e "${gl_kjlan}107. ${color107}PanSou network disk search${gl_kjlan}108. ${color108}LangBot chatbot" + echo -e "${gl_kjlan}109. ${color109}ZFile online network disk${gl_kjlan}110. ${color110}Karakeep bookmark management" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}Multi-format file conversion tool${gl_kjlan}112. ${color112}Lucky large intranet penetration tool" + echo -e "${gl_kjlan}113. ${color113}Firefox browser" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}Third-party application list" + echo -e "${gl_kjlan}Want your app to appear here? Check out the developer guide:${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # Get app description + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # Check installation status (match ID in appno.txt) + # It is assumed here that what is recorded in appno.txt is base_name (i.e. file name) + if echo "$app_numbers" | grep -q "^$base_name$"; then + # If installed: show base_name - description [Installed] (green) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text[Installed]${gl_bai}" + else + # If not installed: display normally + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done - panel_app_manage() { - bt - } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } - install_panel + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}Back up all application data${gl_kjlan}r. ${gl_bai}Restore all app data" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "Please enter your choice:" sub_choice + fi + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="pagoda panel" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } + panel_app_manage() { + bt + } - ;; - 2) + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" + install_panel - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } - panel_app_manage() { - bt - } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + ;; + 2|aapanel) - install_panel - ;; - 3) + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + panel_app_manage() { + bt + } - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - panel_app_uninstall() { - 1pctl uninstall - } + install_panel - install_panel + ;; + 3|1p|1panel) - ;; - 4) + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - docker_rum() { + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + panel_app_uninstall() { + 1pctl uninstall + } + install_panel - } + ;; + 4|npm) - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 - docker_app + docker_rum() { - ;; + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - 5) - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + } - docker_rum() { + local docker_describe="An Nginx reverse proxy tool panel that does not support adding domain name access." + local docker_url="Official website introduction: https://nginxproxymanager.com/" + local docker_use="echo \"Initial username: admin@example.com\"" + local docker_passwd="echo \"Initial password: changeme\"" + local app_size="1" - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + docker_app - } + ;; + 5|openlist) - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 - ;; + docker_rum() { - 6) + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 - docker_rum() { + } - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + local docker_describe="A file listing program that supports multiple storages, web browsing and WebDAV, powered by gin and Solidjs" + local docker_url="Official website introduction: https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "Set login username:" admin + read -e -p "Set login user password:" admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + } - ;; - 7) + local docker_describe="webtop is an Ubuntu-based container. If the IP cannot be accessed, please add a domain name for access." + local docker_url="Official website introduction: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + + + ;; + 7|nezha) + clear + send_stats "Build Nezha" + + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "Build Nezha" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "Nezha Monitoring$check_docker $update_status" - echo "Open source, lightweight and easy-to-use server monitoring and operation and maintenance tools" - echo "Official website construction document: https://nezha.wiki/guide/dashboard.html" - if docker inspect "$docker_name" &>/dev/null; then + echo -e "Nezha monitoring$check_docker $update_status" + echo "Open source, lightweight, easy-to-use server monitoring and operation and maintenance tool" + echo "Official website construction documentation: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. Use" + echo "------------------------" + echo "0. Return to the previous menu" + echo "------------------------" + read -e -p "Enter your selection:" choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1. Use" - echo "------------------------" - echo "0. Return to the previous menu" - echo "------------------------" - read -e -p "Enter your choice:" choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent offline BT magnetic download service" + local docker_url="Official website introduction: https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "Build a post office" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "postal services$check_docker $update_status" + echo "poste.io is an open source mail server solution," + echo "Video introduction: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "Port detection" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}port$portCurrently available${gl_bai}" + else + echo -e "${gl_hong}port$portCurrently unavailable${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "Visit address:" + echo "https://$yuming" + fi - 9) - send_stats "Build a post office" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. Install 2. Update 3. Uninstall" + echo "------------------------" + echo "0. Return to the previous menu" + echo "------------------------" + read -e -p "Enter your selection:" choice - clear - echo -e "Post Office Services$check_docker $update_status" - echo "poste.io is an open source mail server solution." - echo "Video introduction: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "Please set the email domain name, for example mail.yuming.com:" yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "First parse these DNS records" + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "Press any key to continue..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "Port detection" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}port$portCurrently available${gl_bai}" - else - echo -e "${gl_hong}port$portNot currently available${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io - if docker inspect "$docker_name" &>/dev/null; then - yuming=$(cat /home/docker/mail.txt) - echo "Access address:" + + add_app_id + + clear + echo "poste.io has been installed" + echo "------------------------" + echo "You can access poste.io using the following address:" echo "https://$yuming" - fi + echo "" - echo "------------------------" - echo "1. Install 2. Update 3. Uninstall" - echo "------------------------" - echo "0. Return to the previous menu" - echo "------------------------" - read -e -p "Enter your choice:" choice + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "Please set the email domain name, for example, mail.yuming.com:" yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "Parse these DNS records first" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "Press any key to continue..." - read -n 1 -s -r -p "" + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i + yuming=$(cat /home/docker/mail.txt) + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.io has been installed" + echo "------------------------" + echo "You can access poste.io using the following address:" + echo "https://$yuming" + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "App has been uninstalled" + ;; - install jq - install_docker + *) + break + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + esac + break_end + done - clear - echo "poste.io has been installed" - echo "------------------------" - echo "You can access poste.io using the following address:" - echo "https://$yuming" - echo "" + ;; - ;; + 10|rocketchat) - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - clear - echo "poste.io has been installed" - echo "------------------------" - echo "You can access poste.io using the following address:" - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - echo "The app has been uninstalled" - ;; + local app_id="10" + local app_name="Rocket.Chat chat system" + local app_text="Rocket.Chat is an open source team communication platform that supports real-time chat, audio and video calls, file sharing and other functions." + local app_url="Official introduction: https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - *) - break - ;; + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - esac - break_end - done + clear + ip_address + echo "Installation completed" + check_docker_app_ip + } - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "rocket.chat has been installed" + check_docker_app_ip + } - 10) + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "App has been uninstalled" + } - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + docker_app_plus + ;; - clear - ip_address - echo "Installed" - check_docker_app_ip - } - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "rocket.chat has been installed" - check_docker_app_ip - } - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "The app has been uninstalled" - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_plus - ;; + docker_rum() { - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - docker_rum() { + } + local docker_describe="ZenTao is a universal project management software" + local docker_url="Official website introduction: https://www.zentao.net/" + local docker_use="echo \"Initial username: admin\"" + local docker_passwd="echo \"Initial password: 123456\"" + local app_size="2" + docker_app - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + ;; + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 - } + docker_rum() { - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app - ;; + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 - docker_rum() { + } + local docker_describe="Qinglong Panel is a scheduled task management platform" + local docker_url="Official website introduction:${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + ;; + 13|cloudreve) + + local app_id="13" + local app_name="cloudreve network disk" + local app_text="cloudreve is a network disk system that supports multiple cloud storages" + local app_url="Video introduction: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 13) + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "App has been uninstalled" + } - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "Installed" - check_docker_app_ip - } + docker_app_plus + ;; + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + } + local docker_describe="Simple drawing bed is a simple drawing bed program" + local docker_url="Official website introduction:${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "The app has been uninstalled" - } + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_plus - ;; + docker_rum() { - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 + } - docker_rum() { - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + local docker_describe="emby is a master-slave architecture media server software that can be used to organize video and audio on the server and stream audio and video to client devices" + local docker_url="Official website introduction: https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server + } - docker_rum() { + local docker_describe="Speedtest speed measurement panel is a VPS network speed test tool with multiple test functions and can also monitor VPS inbound and outbound traffic in real time." + local docker_url="Official website introduction:${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server + ;; + 17|adguardhome) - } + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; - 17) + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 - docker_rum() { + } - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local docker_describe="AdGuardHome is a network-wide ad blocking and anti-tracking software that will be more than just a DNS server in the future." + local docker_url="Official website introduction: https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + 18|onlyoffice) - ;; + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 + docker_rum() { - 18) + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 - docker_rum() { + } - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + local docker_describe="onlyoffice is an open source online office tool, so powerful!" + local docker_url="Official website introduction: https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; - } + 19|safeline) + send_stats "Build a thunder pool" - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "Thunder pool service$check_docker" + echo "Leichi is a WAF site firewall program panel developed by Changting Technology, which can reverse the site for automated defense." + echo "Video introduction: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" - ;; + echo "------------------------" + echo "1. Install 2. Update 3. Reset password 4. Uninstall" + echo "------------------------" + echo "0. Return to the previous menu" + echo "------------------------" + read -e -p "Enter your selection:" choice - 19) - send_stats "Build a Thunder Pool" + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "Thunder Pool Service$check_docker" - echo "Lei Chi is a WAF site firewall program panel developed by Changting Technology, which can reverse the agency site for automated defense." - echo "Video introduction: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" - if docker inspect "$docker_name" &>/dev/null; then + add_app_id + clear + echo "The Leichi WAF panel has been installed" check_docker_app_ip - fi - echo "" + docker exec safeline-mgt resetadmin - echo "------------------------" - echo "1. Install 2. Update 3. Reset Password 4. Uninstall" - echo "------------------------" - echo "0. Return to the previous menu" - echo "------------------------" - read -e -p "Enter your choice:" choice + ;; - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - clear - echo "The Thunder Pool WAF panel has been installed" - check_docker_app_ip - docker exec safeline-mgt resetadmin + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "The Leichi WAF panel has been updated" + check_docker_app_ip + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "If you are in the default installation directory, the project has been uninstalled now. If you customize the installation directory, you need to go to the installation directory and execute it yourself:" + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer is a lightweight docker container management panel" + local docker_url="Official website introduction: https://www.portainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode is a powerful online code writing tool" + local docker_url="Official website introduction:${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="Uptime Kuma Easy-to-use self-hosted monitoring tool" + local docker_url="Official website introduction:${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos is a lightweight, self-hosted memo center" + local docker_url="Official website introduction:${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "Set login username:" admin + read -e -p "Set login user password:" admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="webtop is based on the Chinese version of Alpine container. If the IP cannot be accessed, please add a domain name for access." + local docker_url="Official website introduction: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="With over 400,000 deployments, Nextcloud is the most popular local content collaboration platform you can download" + local docker_url="Official website introduction: https://nextcloud.com/" + local docker_use="echo \"Account: nextcloud Password:$rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today is an HTTP request scheduled task automatic execution framework" + local docker_url="Official website introduction: https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="dockge is a visual docker-compose container management panel" + local docker_url="Official website introduction:${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed is a lightweight speed testing tool implemented in Javascript that can be used out of the box" + local docker_url="Official website introduction:${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng is a private and private search engine site" + local docker_url="Official website introduction: https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="Photoprism is a very powerful private photo album system" + local docker_url="Official website introduction: https://www.photoprism.app/" + local docker_use="echo \"Account: admin Password:$rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="This is a powerful locally hosted web-based PDF manipulation tool using docker that allows you to perform various operations on PDF files such as split merge, convert, reorganize, add images, rotate, compress, etc." + local docker_url="Official website introduction:${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="This is a powerful charting software. You can draw mind maps, topology diagrams, and flow charts." + local docker_url="Official website introduction: https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel server, NAS navigation panel, Homepage, browser homepage" + local docker_url="Official website introduction: https://doc.sun-panel.top/zh_cn/" + local docker_use="echo \"Account: admin@sun.cc Password: 12345678\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share is a self-buildable file sharing platform and an alternative to WeTransfer" + local docker_url="Official website introduction:${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="Minimalist Moments, high imitation WeChat Moments, record your wonderful life" + local docker_url="Official website introduction:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo \"Account: admin Password: a123456\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat aggregates the mainstream AI large models on the market, ChatGPT/Claude/Gemini/Groq/Ollama" + local docker_url="Official website introduction:${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="It is a multifunctional IP toolbox that allows you to view your own IP information and connectivity, and displays it using a web panel." + local docker_url="Official website introduction:${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "Xiaoya family bucket" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go is a live broadcast recording tool that supports multiple live broadcast platforms" + local docker_url="Official website introduction:${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="Simple online ssh connection tool and sftp tool" + local docker_url="Official website introduction:${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="mouse panel" + local panelurl="Official address:${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm is a powerful online SSH/VNC/RDP connection tool." + local docker_url="Official website introduction:${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="Rustdesk's open source remote desktop (server) is similar to its own Sunflower private server." + local docker_url="Official website introduction: https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"Record your IP and key, which will be used in the remote desktop client. Go to option 44 to install the relay!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="Rustdesk's open source remote desktop (relay) is similar to its own Sunflower private server." + local docker_url="Official website introduction: https://rustdesk.com/zh-cn/" + local docker_use="echo \"Go to the official website to download the remote desktop client: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry is a service for storing and distributing Docker images." + local docker_url="Official website introduction: https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="GHProxy implemented using Go is used to accelerate the pulling of Github repositories in some areas." + local docker_url="Official website introduction: https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="Prometheus monitoring" + local app_text="Prometheus+Grafana enterprise-level monitoring system" + local app_url="Official website introduction: https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "Installation completed" + check_docker_app_ip + echo "The initial username and password are: admin" + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "App has been uninstalled" + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="This is a Prometheus host data collection component, please deploy it on the monitored host." + local docker_url="Official website introduction: https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="This is a Prometheus container data collection component, please deploy it on the monitored host." + local docker_url="Official website introduction: https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="This is a small tool for website change detection, replenishment monitoring and notification" + local docker_url="Official website introduction: https://github.com/dgtlmoon/changedetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE open chick" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker visual panel system provides complete docker management functions." + local docker_url="Official website introduction: https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI is a large language model web page framework that is connected to the new llama3 large language model." + local docker_url="Official website introduction: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMH panel" + local panelurl="Official address: https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI is a large language model web page framework that is connected to the new DeepSeek R1 large language model." + local docker_url="Official website introduction: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="DifyKnowledge Base" + local app_text="It is an open source large language model (LLM) application development platform. Self-hosted training data for AI generation" + local app_url="Official website: https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "Installation completed" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "App has been uninstalled" + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="New generation of large model gateway and AI asset management system" + local app_url="Official website: https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "App has been uninstalled" + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer open source bastion machine" + local app_text="It is an open source privileged access management (PAM) tool. This program occupies port 80 and does not support adding domain names for access." + local app_url="Official introduction: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "Installation completed" + check_docker_app_ip + echo "Initial username: admin" + echo "Initial password: ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "App has been updated" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "App has been uninstalled" + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="Free open source machine translation API, fully self-hosted, and its translation engine is powered by the open source Argos Translate library." + local docker_url="Official website introduction: https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow knowledge base" + local app_text="Open source RAG (Retrieval Augmented Generation) engine based on deep document understanding" + local app_url="Official website: https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "App has been uninstalled" + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI is a large language model web page framework, the official simplified version supports API access to all major models." + local docker_url="Official website introduction: https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="Very useful tool for developers and IT workers" + local docker_url="Official website introduction: https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="It is a powerful automated workflow platform" + local docker_url="Official website introduction: https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="Automatically update your public IP (IPv4/IPv6) to major DNS service providers in real time to achieve dynamic domain name resolution." + local docker_url="Official website introduction: https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="Open source free SSL certificate automation management platform" + local docker_url="Official website introduction: https://allinssl.com" + local docker_use="echo \"Security entrance: /allinssl\"" + local docker_passwd="echo \"Username: allinssl Password: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="Open source free anytime, anywhere SFTP FTP WebDAV file transfer tool" + local docker_url="Official website introduction: https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="Open source AI chatbot framework, supporting WeChat, QQ, and TG access to large AI models" + local docker_url="Official website introduction: https://astrbot.app/" + local docker_use="echo \"Username: astrbot Password: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="Is a lightweight, high-performance music streaming server" + local docker_url="Official website introduction: https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="A password manager that puts you in control of your data" + local docker_url="Official website introduction: https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "Set LibreTV login password:" app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="Free online video search and viewing platform" + local docker_url="Official website introduction: https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="moontv private film and television" + local app_text="Free online video search and viewing platform" + local app_url="Video introduction: https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "Set login username:" admin + read -e -p "Set login user password:" admin_password + read -e -p "Enter authorization code:" shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "App has been uninstalled" + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 + + docker_rum() { + + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest + + + } + + local docker_describe="Your music wizard, designed to help you better manage your music." + local docker_url="Official website introduction: https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + 76|dosgame) + + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 - ;; + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - clear - echo "Thunder Pool WAF panel has been updated" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - echo "If you are the default installation directory, the project has now been uninstalled. If you are customizing the installation directory, you need to go to the installation directory to execute it yourself:" - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; + } - esac - break_end - done + local docker_describe="It is a Chinese DOS game collection website" + local docker_url="Official website introduction: https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - ;; - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 + ;; - docker_rum() { + 77|xunlei) - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 - } + docker_rum() { + read -e -p "Set login username:" app_use + read -e -p "Set login password:" app_passwd - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei - ;; + } - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 + local docker_describe="Xunlei, your offline high-speed BT magnetic download tool" + local docker_url="Official website introduction: https://github.com/cnk3x/xunlei" + local docker_use="echo \"Log in to Xunlei with your mobile phone and enter the invitation code. Invitation code: Xunlei Niutong\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server - } + 78|PandaWiki) + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki is an open source intelligent document management system driven by AI large models. It is strongly recommended not to customize port deployment." + local app_url="Official introduction: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } + docker_app_update() { + docker_app_install + } - docker_rum() { - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + docker_app_uninstall() { + docker_app_install + } - } + docker_app_plus + ;; - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 + 79|beszel) - docker_rum() { + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + docker_rum() { - } + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 + local docker_describe="Beszel is lightweight and easy-to-use server monitoring" + local docker_url="Official website introduction: https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest + 80|linkwarden) + local app_id="80" + local app_name="linkwarden bookmark management" + local app_text="An open source, self-hosted bookmark management platform that supports tagging, search, and team collaboration." + local app_url="Official website: https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - } + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden + # Download the official docker-compose and env files + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; + # Generate random keys and passwords + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env - docker_rum() { + # Add administrator account information + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - } + # Start container + docker compose up -d - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; + clear + echo "Installation completed" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # Keep original variables + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "App uninstalled" + } + + docker_app_plus - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + ;; - docker_rum() { - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd - } + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet video conference" + local app_text="An open source secure video conferencing solution that supports multi-person online conferencing, screen sharing and encrypted communication." + local app_url="Official website: https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + docker_app_install() { - docker_rum() { + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - } + } - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 + } - docker_rum() { + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "App has been uninstalled" + } - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest + docker_app_plus - } + ;; - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 - docker_rum() { + 82|gpt-load) - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - } + docker_rum() { - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + read -e -p "set up${docker_name}Login key (sk-a combination of letters and numbers starting with) such as: sk-159kejilionyyds163:" app_passwd - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest - docker_rum() { + } - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + local docker_describe="High-performance AI interface transparent proxy service" + local docker_url="Official website introduction: https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 83|komari) - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 + docker_rum() { - docker_rum() { + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + } - } + local docker_describe="Lightweight self-hosted server monitoring tool" + local docker_url="Official website introduction: https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"Default account: admin Default password: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 - docker_rum() { + 84|wallos) - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 - } + docker_rum() { - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + } - docker_rum() { + local docker_describe="Open source personal subscription tracker for financial management" + local docker_url="Official website introduction: https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + ;; - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 85|immich) + local app_id="85" + local app_name="immich picture video manager" + local app_text="High-performance self-hosted photo and video management solution." + local app_url="Official website introduction: https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - docker_rum() { + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="Official website introduction:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "App has been uninstalled" + } - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + docker_app_plus - docker_rum() { - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } + ;; - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + 86|jellyfin) - docker_rum() { + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + docker_rum() { - } + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 38) - send_stats "Xiaoya Family Bucket" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; + } - 39) + local docker_describe="Is an open source media server software" + local docker_url="Official website introduction: https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 87|synctv) + + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 + + docker_rum() { + + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv + + } + + local docker_describe="A program to watch movies and live broadcasts together remotely. It provides simultaneous viewing, live broadcast, chat and other functions" + local docker_url="Official website introduction: https://github.com/synctv-org/synctv" + local docker_use="echo \"Initial account and password: root. Please change the login password in time after logging in\"" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 88|owncast) + + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 + + docker_rum() { + + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + + } + + local docker_describe="Open source, free self-built live broadcast platform" + local docker_url="Official website introduction: https://owncast.online" + local docker_use="echo \"The access address is followed by /admin to access the administrator page\"" + local docker_passwd="echo \"Initial account: admin Initial password: abc123 Please change the login password in time after logging in\"" + local app_size="1" + docker_app + + ;; + + + + 89|file-code-box) + + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 + + docker_rum() { + + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest + + } + + local docker_describe="Share texts and files with anonymous passwords, and pick up files like express delivery" + local docker_url="Official website introduction: https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"The access address is followed by /#/admin to access the administrator page\"" + local docker_passwd="echo \"Administrator password: FileCodeBox2023\"" + local app_size="1" + docker_app + + ;; + + + + + 90|matrix) + + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 + + docker_rum() { + + add_yuming + + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate fi - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - docker_rum() { + echo "Create an initial user or administrator. Please set the following username and password and whether you are an administrator." + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - } + docker restart matrix - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + } - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Matrix is ​​a decentralized chat protocol" + local docker_url="Official website introduction: https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 41) + ;; - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } - panel_app_manage() { - panel-cli - } + 91|gitea) - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } + local app_id="91" - install_panel + local app_name="gitea private code repository" + local app_text="A free new generation code hosting platform that provides an experience close to GitHub." + local app_url="Video introduction: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - ;; + docker_app_install() { + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - docker_rum() { - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - } - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "App has been uninstalled" + } - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + docker_app_plus - docker_rum() { + ;; - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs - } - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + 92|filebrowser) - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - docker_rum() { + docker_rum() { - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - } + } - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Is a web-based file manager" + local docker_url="Official website introduction: https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + ;; - docker_rum() { + 93|dufs) - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 - } + docker_rum() { - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 + } - docker_rum() { + local docker_describe="Minimalist static file server, supports upload and download" + local docker_url="Official website introduction: https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest + ;; - } + 94|gopeed) - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 - 47) + docker_rum() { + read -e -p "Set login username:" app_use + read -e -p "Set login password:" app_passwd + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + } - docker_app_install() { - prometheus_install - clear - ip_address - echo "Installed" - check_docker_app_ip - echo "The initial username and password are: admin" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } + local docker_describe="Distributed high-speed download tool, supporting multiple protocols" + local docker_url="Official website introduction: https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest + ;; - rm -rf /home/docker/monitoring - echo "The app has been uninstalled" - } - docker_app_plus - ;; - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 + 95|paperless) - docker_rum() { + local app_id="95" - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + local app_name="paperless document management platform" + local app_text="An open source electronic document management system, its main purpose is to digitize and manage your paper documents." + local app_url="Video introduction: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" + docker_app_install() { - } + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - docker_rum() { - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } - } - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "App has been uninstalled" + } + docker_app_plus - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 + ;; - docker_rum() { - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest - } + 96|2fauth) - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="96" + local app_name="2FAuth self-hosted two-step authenticator" + local app_text="Self-hosted two-factor authentication (2FA) account management and verification code generation tool." + local app_url="Official website: https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" + + docker_app_install() { + + add_yuming + + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth + + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml + + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 51) clear - send_stats "PVE Chicken" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + echo "Installation completed" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "App has been uninstalled" + } - docker_rum() { + docker_app_plus - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite + ;; - } - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + 97|wgs) - docker_rum() { + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + docker_rum() { - } + read -e -p "Please enter the number of clients in the network (default 5):" COUNT + COUNT=${COUNT:-5} + read -e -p "Please enter the WireGuard network segment (default 10.13.13.0):" NETWORK + NETWORK=${NETWORK:-10.13.13.0} - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) - 54) + ip link delete wg0 &>/dev/null - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } - panel_app_manage() { - panel_app_install - } + sleep 3 - panel_app_uninstall() { - panel_app_install - } + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - install_panel - ;; + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - 55) - frps_panel - ;; + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' - 56) - frpc_panel - ;; + docker restart wireguard - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + sleep 2 + echo + echo -e "${gl_huang}All client QR code configurations:${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}All client configuration codes:${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}Configure all outputs for each client. The usage method is as follows:${gl_bai}" + echo -e "${gl_lv}1. Download the wg APP on your mobile phone and scan the QR code above to quickly connect to the Internet.${gl_bai}" + echo -e "${gl_lv}2. Download the client for Windows and copy the configuration code to connect to the network.${gl_bai}" + echo -e "${gl_lv}3. Use a script to deploy the WG client on Linux and copy the configuration code to connect to the network.${gl_bai}" + echo -e "${gl_lv}Official client download method: https://www.wireguard.com/install/${gl_bai}" + break_end - docker_rum() { + } - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + local docker_describe="Modern, high-performance virtual private network tools" + local docker_url="Official website introduction: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + 98|wgc) - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + docker_rum() { - docker compose up -d - clear - echo "Installed" - check_docker_app_ip - } + mkdir -p /home/docker/wireguard/config/ - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "The app has been uninstalled" - } + # Create directory if it does not exist + mkdir -p "$(dirname "$CONFIG_FILE")" - docker_app_plus + echo "Please paste your client configuration and press Enter twice to save:" - ;; + # initialize variables + input="" + empty_line_count=0 - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + # Read user input line by line + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + # Write configuration file + echo "$input" > "$CONFIG_FILE" - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + echo "Client configuration saved to$CONFIG_FILE" + ip link delete wg0 &>/dev/null - docker compose up -d - clear - echo "Installed" - check_docker_app_ip - } + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + sleep 3 - docker compose up -d - clear - echo "Installed" - check_docker_app_ip + docker logs wireguardc - } + break_end - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "The app has been uninstalled" - } + } - docker_app_plus + local docker_describe="Modern, high-performance virtual private network tools" + local docker_url="Official website introduction: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - ;; + ;; - 60) + 99|dsm) - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" + local app_id="99" - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "Installed" - check_docker_app_ip - echo "Initial username: admin" - echo "Initial password: ChangeMe" - } + local app_name="dsm synology virtual machine" + local app_text="Virtual DSM in Docker container" + local app_url="Official website: https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" + docker_app_install() { - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "The app has been updated" - } + read -e -p "Set the number of CPU cores (default 2):" CPU_CORES + local CPU_CORES=${CPU_CORES:-2} + read -e -p "Set memory size (default 4G):" RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "The app has been uninstalled" - } + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - docker_app_plus - ;; + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d - docker_rum() { + clear + echo "Installation completed" + check_docker_app_ip + } - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru - } + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "App has been uninstalled" + } + docker_app_plus - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + ;; - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "Installed" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "The app has been uninstalled" - } - docker_app_plus + 100|syncthing) - ;; + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local docker_describe="An open source peer-to-peer file synchronization tool, similar to Dropbox and Resilio Sync, but completely decentralized." + local docker_url="Official website introduction: https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main - } + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI video generation tool" + local app_text="MoneyPrinterTurbo is a tool that uses AI large models to synthesize high-definition short videos" + local app_url="Official website: https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "App has been uninstalled" + } - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + docker_app_plus - docker_rum() { + ;; - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" - } + 102|vocechat) - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - 66) - yt_menu_pro - ;; + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + } - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local docker_describe="It is a personal cloud social media chat service that supports independent deployment." + local docker_url="Official website introduction: https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + 103|umami) + local app_id="103" + local app_name="Umami website statistics tool" + local app_text="Open source, lightweight, privacy-friendly website analysis tool, similar to Google Analytics." + local app_url="Official website: https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + echo "Initial username: admin" + echo "Initial password: umami" + } + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "App has been uninstalled" + } - docker_rum() { + docker_app_plus - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo + ;; - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + 104|nginx-stream) + stream_panel + ;; - } - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 105|siyuan) + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 + docker_rum() { - docker_rum() { + read -e -p "Set login password:" app_passwd - mkdir -p /home/docker/astrbot/data + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + } - } + local docker_describe="Siyuan Notes is a privacy-first knowledge management system" + local docker_url="Official website introduction: https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + 106|drawnix) - docker_rum() { + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_rum() { - } + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="It is a powerful open source whiteboard tool that integrates mind maps, flow charts, etc." + local docker_url="Official website introduction: https://github.com/plait-board/drawnix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { + 107|pansou) - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou is a high-performance network disk resource search API service." + local docker_url="Official website introduction: https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 73) - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 - docker_rum() { + 108|langbot) + local app_id="108" + local app_name="LangBot chatbot" + local app_text="It is an open source large language model native instant messaging robot development platform." + local app_url="Official website: https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - read -e -p "Set the LibreTV login password:" app_passwd + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "App has been uninstalled" + } - ;; + docker_app_plus + ;; - 74) - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + 109|zfile) - docker_rum() { + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - read -e -p "Set the MoonTV login password:" app_passwd + docker_rum() { - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest - } + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="It is an online network disk program suitable for individuals or small teams." + local docker_url="Official website introduction: https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 75) + ;; - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 - docker_rum() { + 110|karakeep) + local app_id="110" + local app_name="karakeep bookmark management" + local app_text="is a self-hosted bookmarking app with artificial intelligence capabilities designed for data hoarders." + local app_url="Official website: https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + docker compose up -d + clear + echo "Installation completed" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "App has been uninstalled" + } + docker_app_plus - ;; + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 + 111|convertx) - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - } + docker_rum() { - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} + } - ;; + local docker_describe="It is a powerful multi-format file conversion tool (supports documents, images, audio and video, etc.) It is strongly recommended to add domain name access" + local docker_url="Project address: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - 77) + ;; - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 - docker_rum() { + 112|lucky) - read -e -p "set up${docker_name}Login username:" app_use - read -e -p "set up${docker_name}Login password:" app_passwd + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # Since Lucky uses the host network mode, the port here is only for record/explanation reference and is actually controlled by the application itself (default 16601) + local docker_port=8112 - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + docker_rum() { - } + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + echo "Waiting for Lucky to initialize..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - ;; + } + local docker_describe="Lucky is a large intranet penetration and port forwarding management tool that supports DDNS, reverse proxy, WOL and other functions." + local docker_url="Project address: https://github.com/gdy666/lucky" + local docker_use="echo \"Default account password: 666\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 78) - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + 113|firefox) - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 - docker_app_update() { - docker_app_install - } + docker_rum() { + read -e -p "Set login password:" admin_password - docker_app_uninstall() { - docker_app_install - } + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - docker_app_plus - ;; + local docker_describe="It is a Firefox browser running in Docker that supports direct access to the desktop browser interface through the web page." + local docker_url="Project address: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 79) + b) + clear + send_stats "All application backup" - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}Backing up$backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_rum() { + while true; do + clear + echo "Backup file created: /$backup_filename" + read -e -p "Do you want to transfer backup data to a remote server? (Y/N):" choice + case "$choice" in + [Yy]) + read -e -p "Please enter the remote server IP:" remote_ip + read -e -p "Target server SSH port [default 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel + if [ -z "$remote_ip" ]; then + echo "Error: Please enter the remote server IP." + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "File transferred to remote server/root directory." + else + echo "The file to be transferred was not found." + fi + break + ;; + *) + echo "Note: The current backup only includes docker projects, and does not include data backup of website building panels such as Pagoda and 1panel." + break + ;; + esac + done - } + ;; - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + r) + root_use + send_stats "Restore all apps" + echo "Available application backups" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "Press the Enter key to restore the latest backup, enter the backup file name to restore the specified backup, enter 0 to exit:" filename - ;; + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # If the user does not enter a file name, the latest compressed package is used + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}Unzipping$filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "The application data has been restored. Currently, please manually enter the specified application menu and update the application to restore the application." + else + echo "No compressed package found." + fi + ;; - 0) - kejilion - ;; - *) - echo "Invalid input!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}Error: Not found with number${sub_choice}application configuration${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do clear send_stats "Backend workspace" echo -e "Backend workspace" - echo -e "The system will provide you with a workspace that can be run on the backend, which you can use to perform long-term tasks." - echo -e "Even if you disconnect SSH, tasks in the workspace will not be interrupted, and tasks in the background will be resident." - echo -e "${gl_huang}hint:${gl_bai}After entering the workspace, use Ctrl+b and press d alone to exit the workspace!" + echo -e "The system will provide you with a workspace that can run permanently in the background, which you can use to perform long-term tasks." + echo -e "Even if you disconnect SSH, the tasks in the workspace will not be interrupted, and the tasks will remain in the background." + echo -e "${gl_huang}hint:${gl_bai}After entering the workspace, use Ctrl+b and then press d alone to exit the workspace!" echo -e "${gl_kjlan}------------------------" echo "List of currently existing workspaces" echo -e "${gl_kjlan}------------------------" tmux list-sessions echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Workspace No. 1" - echo -e "${gl_kjlan}2. ${gl_bai}Workspace No. 2" - echo -e "${gl_kjlan}3. ${gl_bai}Workspace No. 3" - echo -e "${gl_kjlan}4. ${gl_bai}Workspace No. 4" + echo -e "${gl_kjlan}1. ${gl_bai}Work Area 1" + echo -e "${gl_kjlan}2. ${gl_bai}Work Area 2" + echo -e "${gl_kjlan}3. ${gl_bai}Work Area 3" + echo -e "${gl_kjlan}4. ${gl_bai}Work Area 4" echo -e "${gl_kjlan}5. ${gl_bai}Workspace No. 5" - echo -e "${gl_kjlan}6. ${gl_bai}Workspace No. 6" - echo -e "${gl_kjlan}7. ${gl_bai}Workspace No. 7" - echo -e "${gl_kjlan}8. ${gl_bai}Workspace No. 8" + echo -e "${gl_kjlan}6. ${gl_bai}Work Area 6" + echo -e "${gl_kjlan}7. ${gl_bai}Work Area 7" + echo -e "${gl_kjlan}8. ${gl_bai}Work Area 8" echo -e "${gl_kjlan}9. ${gl_bai}Workspace No. 9" - echo -e "${gl_kjlan}10. ${gl_bai}Workspace No. 10" + echo -e "${gl_kjlan}10. ${gl_bai}Workspace 10" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}SSH resident mode${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}22. ${gl_bai}Create/enter the workspace" + echo -e "${gl_kjlan}22. ${gl_bai}Create/enter workspace" echo -e "${gl_kjlan}23. ${gl_bai}Inject commands into the background workspace" - echo -e "${gl_kjlan}24. ${gl_bai}Delete the specified workspace" + echo -e "${gl_kjlan}24. ${gl_bai}Delete specified workspace" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in @@ -10676,7 +13165,7 @@ linux_work() { clear install tmux local SESSION_NAME="work1" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; @@ -10684,63 +13173,63 @@ linux_work() { clear install tmux local SESSION_NAME="work2" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 3) clear install tmux local SESSION_NAME="work3" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 4) clear install tmux local SESSION_NAME="work4" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 5) clear install tmux local SESSION_NAME="work5" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 6) clear install tmux local SESSION_NAME="work6" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 7) clear install tmux local SESSION_NAME="work7" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 8) clear install tmux local SESSION_NAME="work8" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 9) clear install tmux local SESSION_NAME="work9" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; 10) clear install tmux local SESSION_NAME="work10" - send_stats "Start the workspace$SESSION_NAME" + send_stats "Start workspace$SESSION_NAME" tmux_run ;; @@ -10748,30 +13237,30 @@ linux_work() { while true; do clear if grep -q 'tmux attach-session -t sshd || tmux new-session -s sshd' ~/.bashrc; then - local tmux_sshd_status="${gl_lv}开启${gl_bai}" + local tmux_sshd_status="${gl_lv}turn on${gl_bai}" else - local tmux_sshd_status="${gl_hui}关闭${gl_bai}" + local tmux_sshd_status="${gl_hui}closure${gl_bai}" fi send_stats "SSH resident mode" echo -e "SSH resident mode${tmux_sshd_status}" - echo "After SSH connection is enabled, it will directly enter the resident mode and return to the previous working state." + echo "After opening the SSH connection, it will directly enter the resident mode and return directly to the previous working state." echo "------------------------" - echo "1. Turn on 2. Turn off" + echo "1. On 2. Off" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" gongzuoqu_del + read -e -p "Please enter your choice:" gongzuoqu_del case "$gongzuoqu_del" in 1) install tmux local SESSION_NAME="sshd" - send_stats "Start the workspace$SESSION_NAME" - grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\n# Automatically enter the tmux session\nif [[ -z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc + send_stats "Start workspace$SESSION_NAME" + grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\n# Automatically enter tmux session\nif [[ -z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc source ~/.bashrc tmux_run ;; 2) - sed -i '/# 自动进入 tmux 会话/,+4d' ~/.bashrc + sed -i '/# Automatically enter tmux session/,+4d' ~/.bashrc tmux kill-window -t sshd ;; *) @@ -10797,7 +13286,7 @@ linux_work() { 24) read -e -p "Please enter the name of the workspace you want to delete:" gongzuoqu_name tmux kill-window -t $gongzuoqu_name - send_stats "Delete the workspace" + send_stats "Delete workspace" ;; 0) @@ -10823,6 +13312,101 @@ linux_work() { +# Intelligent switching mirror source function +switch_mirror() { + # Optional parameter, default is false + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # Get user country + local country + country=$(curl -s ipinfo.io/country) + + echo "Countries detected:$country" + + if [ "$country" = "CN" ]; then + echo "Use domestic mirror sources..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "Use official mirror source..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "ssh defense" + while true; do + + check_f2b_status + echo -e "SSH defense program$check_f2b_status" + echo "fail2ban is an SSH tool to prevent brute force cracking" + echo "Official website introduction:${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. Install a defense program" + echo "------------------------" + echo "2. View SSH interception records" + echo "3. Real-time log monitoring" + echo "------------------------" + echo "9. Uninstall the defense program" + echo "------------------------" + echo "0. Return to the previous menu" + echo "------------------------" + read -e -p "Please enter your choice:" sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban defense program has been uninstalled" + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { @@ -10830,52 +13414,53 @@ linux_Settings() { while true; do clear # send_stats "System Tools" - echo -e "System Tools" + echo -e "system tools" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Set script startup shortcut keys${gl_kjlan}2. ${gl_bai}Modify the login password" + echo -e "${gl_kjlan}1. ${gl_bai}Set script startup shortcut key${gl_kjlan}2. ${gl_bai}Change login password" echo -e "${gl_kjlan}3. ${gl_bai}ROOT password login mode${gl_kjlan}4. ${gl_bai}Install the specified version of Python" - echo -e "${gl_kjlan}5. ${gl_bai}Open all ports${gl_kjlan}6. ${gl_bai}Modify the SSH connection port" - echo -e "${gl_kjlan}7. ${gl_bai}Optimize DNS address${gl_kjlan}8. ${gl_bai}One-click reinstallation system${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}9. ${gl_bai}Disable ROOT account to create a new account${gl_kjlan}10. ${gl_bai}Switch priority ipv4/ipv6" + echo -e "${gl_kjlan}5. ${gl_bai}Open all ports${gl_kjlan}6. ${gl_bai}Modify SSH connection port" + echo -e "${gl_kjlan}7. ${gl_bai}Optimize DNS address${gl_kjlan}8. ${gl_bai}Reinstall the system with one click${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}9. ${gl_bai}Disable ROOT account and create new account${gl_kjlan}10. ${gl_bai}Switch priority ipv4/ipv6" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}11. ${gl_bai}Check port occupation status${gl_kjlan}12. ${gl_bai}Modify virtual memory size" - echo -e "${gl_kjlan}13. ${gl_bai}User Management${gl_kjlan}14. ${gl_bai}User/Password Generator" + echo -e "${gl_kjlan}13. ${gl_bai}User management${gl_kjlan}14. ${gl_bai}User/password generator" echo -e "${gl_kjlan}15. ${gl_bai}System time zone adjustment${gl_kjlan}16. ${gl_bai}Set up BBR3 acceleration" - echo -e "${gl_kjlan}17. ${gl_bai}Firewall Advanced Manager${gl_kjlan}18. ${gl_bai}Modify the host name" - echo -e "${gl_kjlan}19. ${gl_bai}Switch system update source${gl_kjlan}20. ${gl_bai}Timing task management" + echo -e "${gl_kjlan}17. ${gl_bai}Firewall Advanced Manager${gl_kjlan}18. ${gl_bai}Modify hostname" + echo -e "${gl_kjlan}19. ${gl_bai}Switch system update source${gl_kjlan}20. ${gl_bai}Scheduled task management" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}Native host parsing${gl_kjlan}22. ${gl_bai}SSH Defense Program" - echo -e "${gl_kjlan}23. ${gl_bai}Automatic shutdown of current limit${gl_kjlan}24. ${gl_bai}ROOT private key login mode" - echo -e "${gl_kjlan}25. ${gl_bai}TG-bot system monitoring and early warning${gl_kjlan}26. ${gl_bai}Fix OpenSSH high-risk vulnerabilities (Xiuyuan)" - echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linux kernel upgrade${gl_kjlan}28. ${gl_bai}Optimization of kernel parameters in Linux system${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}29. ${gl_bai}Virus scanning tool${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}File Manager" + echo -e "${gl_kjlan}21. ${gl_bai}Native host resolution${gl_kjlan}22. ${gl_bai}SSH defense program" + echo -e "${gl_kjlan}23. ${gl_bai}Current limiting automatic shutdown${gl_kjlan}24. ${gl_bai}ROOT private key login mode" + echo -e "${gl_kjlan}25. ${gl_bai}TG-bot system monitoring and early warning${gl_kjlan}26. ${gl_bai}Fix OpenSSH high-risk vulnerabilities" + echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linux kernel upgrade${gl_kjlan}28. ${gl_bai}Linux system kernel parameter optimization${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}29. ${gl_bai}Virus scanning tools${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}file manager" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}31. ${gl_bai}Switch system language${gl_kjlan}32. ${gl_bai}Command line beautification tool${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}Set up a system recycling bin${gl_kjlan}34. ${gl_bai}System backup and recovery" + echo -e "${gl_kjlan}33. ${gl_bai}Set up system recycle bin${gl_kjlan}34. ${gl_bai}System backup and recovery" echo -e "${gl_kjlan}35. ${gl_bai}ssh remote connection tool${gl_kjlan}36. ${gl_bai}Hard disk partition management tool" echo -e "${gl_kjlan}37. ${gl_bai}Command line history${gl_kjlan}38. ${gl_bai}rsync remote synchronization tool" + echo -e "${gl_kjlan}39. ${gl_bai}Command Favorites${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}Message board${gl_kjlan}66. ${gl_bai}One-stop system optimization${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}99. ${gl_bai}Restart the server${gl_kjlan}100. ${gl_bai}Privacy and Security" + echo -e "${gl_kjlan}41. ${gl_bai}message board${gl_kjlan}66. ${gl_bai}One-stop system tuning${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}99. ${gl_bai}Restart the server${gl_kjlan}100. ${gl_bai}Privacy and security" echo -e "${gl_kjlan}101. ${gl_bai}Advanced usage of k command${gl_huang}★${gl_bai} ${gl_kjlan}102. ${gl_bai}Uninstall tech lion script" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) while true; do clear - read -e -p "Please enter your shortcut key (enter 0 to exit):" kuaijiejian + read -e -p "Please enter your shortcut keys (enter 0 to exit):" kuaijiejian if [ "$kuaijiejian" == "0" ]; then break_end linux_Settings fi find /usr/local/bin/ -type l -exec bash -c 'test "$(readlink -f {})" = "/usr/local/bin/k" && rm -f {}' \; ln -s /usr/local/bin/k /usr/local/bin/$kuaijiejian - echo "Shortcut keys are set" - send_stats "Script shortcut keys have been set" + echo "Shortcut keys have been set" + send_stats "Script shortcut key has been set" break_end linux_Settings done @@ -10896,21 +13481,21 @@ linux_Settings() { 4) root_use send_stats "py version management" - echo "Python version management" + echo "python version management" echo "Video introduction: https://www.bilibili.com/video/BV1Pm42157cK?t=0.1" echo "---------------------------------------" - echo "This feature seamlessly installs any version officially supported by python!" + echo "This function can seamlessly install any version officially supported by python!" local VERSION=$(python3 -V 2>&1 | awk '{print $2}') echo -e "Current python version number:${gl_huang}$VERSION${gl_bai}" echo "------------" - echo "Recommended version: 3.12 3.11 3.10 3.9 3.8 2.7" - echo "Query more versions: https://www.python.org/downloads/" + echo "Recommended versions: 3.12 3.11 3.10 3.9 3.8 2.7" + echo "Check more versions: https://www.python.org/downloads/" echo "------------" read -e -p "Enter the python version number you want to install (enter 0 to exit):" py_new_v if [[ "$py_new_v" == "0" ]]; then - send_stats "Script PY Management" + send_stats "Script PY management" break_end linux_Settings fi @@ -10973,13 +13558,13 @@ EOF local VERSION=$(python -V 2>&1 | awk '{print $2}') echo -e "Current python version number:${gl_huang}$VERSION${gl_bai}" - send_stats "Switch script PY version" + send_stats "Script PY version switching" ;; 5) root_use - send_stats "Open port" + send_stats "open port" iptables_open remove iptables-persistent ufw firewalld iptables-services > /dev/null 2>&1 echo "All ports are open" @@ -10996,13 +13581,13 @@ EOF # Read the current SSH port number local current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') - # Print the current SSH port number + # Print current SSH port number echo -e "The current SSH port number is:${gl_huang}$current_port ${gl_bai}" echo "------------------------" - echo "Numbers with port numbers ranging from 1 to 65535. (Enter 0 to exit)" + echo "The port number ranges from 1 to 65535. (Enter 0 to exit)" - # Prompt the user to enter a new SSH port number + # Prompt user for new SSH port number read -e -p "Please enter the new SSH port number:" new_port # Determine whether the port number is within the valid range @@ -11014,13 +13599,13 @@ EOF send_stats "Exit SSH port modification" break else - echo "The port number is invalid, please enter a number between 1 and 65535." - send_stats "Invalid SSH port input" + echo "The port number is invalid. Please enter a number between 1 and 65535." + send_stats "Invalid SSH port entered" break_end fi else - echo "The input is invalid, please enter the number." - send_stats "Invalid SSH port input" + echo "Invalid input, please enter a number." + send_stats "Invalid SSH port entered" break_end fi done @@ -11039,8 +13624,8 @@ EOF ;; 9) root_use - send_stats "New users disable root" - read -e -p "Please enter the new username (enter 0 to exit):" new_username + send_stats "Disable root for new users" + read -e -p "Please enter a new username (enter 0 to exit):" new_username if [ "$new_username" == "0" ]; then break_end linux_Settings @@ -11049,11 +13634,13 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root - echo "The operation has been completed." + echo "The operation is complete." ;; @@ -11064,38 +13651,37 @@ EOF clear echo "Set v4/v6 priority" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then echo -e "Current network priority settings:${gl_huang}IPv4${gl_bai}priority" else echo -e "Current network priority settings:${gl_huang}IPv6${gl_bai}priority" fi + echo "" echo "------------------------" - echo "1. IPv4 priority 2. IPv6 priority 3. IPv6 repair tool" + echo "1. IPv4 first 2. IPv6 first 3. IPv6 repair tool" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Choose a preferred network:" choice + read -e -p "Choose your preferred network:" choice case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "Switched to IPv4 priority" - send_stats "Switched to IPv4 priority" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 - echo "Switched to IPv6 priority" - send_stats "Switched to IPv6 priority" + rm -f /etc/gai.conf + echo "Switched to IPv6 first" + send_stats "Switched to IPv6 first" ;; 3) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "This function is provided by the master jhb, thanks to him!" - send_stats "ipv6 fix" + echo "This function is provided by jhb, thank him!" + send_stats "ipv6 repair" ;; *) @@ -11123,11 +13709,11 @@ EOF echo -e "Current virtual memory:${gl_huang}$swap_info${gl_bai}" echo "------------------------" - echo "1. Assign 1024M 2. Assign 2048M 3. Assign 4096M 4. Custom size" + echo "1. Allocate 1024M 2. Allocate 2048M 3. Allocate 4096M 4. Custom size" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case "$choice" in 1) @@ -11141,7 +13727,7 @@ EOF ;; 3) - send_stats "4G virtual memory has been set" + send_stats "4G virtual memory has been set up" add_swap 4096 ;; @@ -11149,7 +13735,7 @@ EOF 4) read -e -p "Please enter the virtual memory size (unit M):" new_swap add_swap "$new_swap" - send_stats "Custom virtual memory has been set" + send_stats "Custom virtual memory set" ;; *) @@ -11162,10 +13748,10 @@ EOF 13) while true; do root_use - send_stats "User Management" - echo "User List" + send_stats "User management" + echo "User list" echo "----------------------------------------------------------------------------" - printf "%-24s %-34s %-20s %-10s\n" "用户名" "用户权限" "用户组" "sudo权限" + printf "%-24s %-34s %-20s %-10s\n" "username" "User permissions" "User group" "sudo permissions" while IFS=: read -r username _ userid groupid _ _ homedir shell; do local groups=$(groups "$username" | cut -d : -f 2) local sudo_status=$(sudo -n -lU "$username" 2>/dev/null | grep -q '(ALL : ALL)' && echo "Yes" || echo "No") @@ -11174,58 +13760,62 @@ EOF echo "" - echo "Account operation" + echo "Account operations" echo "------------------------" - echo "1. Create a normal account 2. Create a premium account" + echo "1. Create a regular account 2. Create a premium account" echo "------------------------" - echo "3. Give the highest permissions 4. Cancel the highest permissions" + echo "3. Grant the highest authority 4. Remove the highest authority" echo "------------------------" - echo "5. Delete the account" + echo "5. Delete account" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - # Prompt the user to enter a new username + # Prompt user for new username read -e -p "Please enter a new username:" new_username - # Create a new user and set a password + # Create new user and set password useradd -m -s /bin/bash "$new_username" passwd "$new_username" - echo "The operation has been completed." + echo "The operation is complete." ;; 2) - # Prompt the user to enter a new username + # Prompt user for new username read -e -p "Please enter a new username:" new_username - # Create a new user and set a password + # Create new user and set password useradd -m -s /bin/bash "$new_username" passwd "$new_username" - # Grant new users sudo permissions + # Give the new user sudo permissions echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers - echo "The operation has been completed." + install sudo + + echo "The operation is complete." ;; 3) - read -e -p "Please enter your username:" username - # Grant new users sudo permissions + read -e -p "Please enter username:" username + # Give the new user sudo permissions echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) - read -e -p "Please enter your username:" username + read -e -p "Please enter username:" username # Remove user's sudo permissions from sudoers file sed -i "/^$username\sALL=(ALL:ALL)\sALL/d" /etc/sudoers ;; 5) - read -e -p "Please enter the username to delete:" username - # Delete the user and its home directory + read -e -p "Please enter the username you want to delete:" username + # Delete users and their home directories userdel -r "$username" ;; @@ -11238,16 +13828,16 @@ EOF 14) clear - send_stats "User Information Generator" - echo "Random username" + send_stats "User information generator" + echo "random username" echo "------------------------" for i in {1..5}; do username="user$(< /dev/urandom tr -dc _a-z0-9 | head -c6)" - echo "Random username$i: $username" + echo "random username$i: $username" done echo "" - echo "Random name" + echo "random name" echo "------------------------" local first_names=("John" "Jane" "Michael" "Emily" "David" "Sophia" "William" "Olivia" "James" "Emma" "Ava" "Liam" "Mia" "Noah" "Isabella") local last_names=("Smith" "Johnson" "Brown" "Davis" "Wilson" "Miller" "Jones" "Garcia" "Martinez" "Williams" "Lee" "Gonzalez" "Rodriguez" "Hernandez") @@ -11269,11 +13859,11 @@ EOF done echo "" - echo "16-bit random password" + echo "16-digit random password" echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) - echo "Random password$i: $password" + echo "random password$i: $password" done echo "" @@ -11281,7 +13871,7 @@ EOF echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32) - echo "Random password$i: $password" + echo "random password$i: $password" done echo "" @@ -11305,30 +13895,30 @@ EOF echo "Current system time:$current_time" echo "" - echo "Time zone switching" + echo "time zone switch" echo "------------------------" echo "Asia" - echo "1. Shanghai time in China 2. Hong Kong time in China" - echo "3. Tokyo time in Japan 4. Seoul time in South Korea" - echo "5. Singapore time 6. Kolkata time in India" - echo "7. Dubai time in the UAE 8. Sydney time in Australia" - echo "9. Time in Bangkok, Thailand" + echo "1. Shanghai, China time 2. Hong Kong time, China" + echo "3. Tokyo, Japan time 4. Seoul, South Korea time" + echo "5. Singapore time 6. Kolkata, India time" + echo "7. Dubai, United Arab Emirates time 8. Sydney, Australia time" + echo "9. Bangkok, Thailand time" echo "------------------------" echo "Europe" - echo "11. London time in the UK 12. Paris time in France" - echo "13. Berlin time, Germany 14. Moscow time, Russia" - echo "15. Utrecht time in the Netherlands 16. Madrid time in Spain" + echo "11. London, UK time 12. Paris, France time" + echo "13. Berlin, Germany time 14. Moscow, Russia time" + echo "15. Utracht Time, Netherlands 16. Madrid Time, Spain" echo "------------------------" echo "America" - echo "21. Western Time 22. Eastern Time" - echo "23. Canadian time 24. Mexican time" + echo "21. US Western Time 22. US Eastern Time" + echo "23. Canada time 24. Mexico time" echo "25. Brazil time 26. Argentina time" echo "------------------------" - echo "31. UTC Global Standard Time" + echo "31. UTC global standard time" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in @@ -11371,21 +13961,21 @@ EOF 18) root_use - send_stats "Modify the host name" + send_stats "Modify hostname" while true; do clear local current_hostname=$(uname -n) - echo -e "Current host name:${gl_huang}$current_hostname${gl_bai}" + echo -e "Current hostname:${gl_huang}$current_hostname${gl_bai}" echo "------------------------" - read -e -p "Please enter the new host name (enter 0 to exit):" new_hostname + read -e -p "Please enter a new hostname (enter 0 to exit):" new_hostname if [ -n "$new_hostname" ] && [ "$new_hostname" != "0" ]; then if [ -f /etc/alpine-release ]; then # Alpine echo "$new_hostname" > /etc/hostname hostname "$new_hostname" else - # Other systems, such as Debian, Ubuntu, CentOS, etc. + # Other systems such as Debian, Ubuntu, CentOS, etc. hostnamectl set-hostname "$new_hostname" sed -i "s/$current_hostname/$new_hostname/g" /etc/hostname systemctl restart systemd-hostnamed @@ -11403,11 +13993,11 @@ EOF echo "::1 $new_hostname localhost localhost.localdomain ipv6-localhost ipv6-loopback" >> /etc/hosts fi - echo "The host name has been changed to:$new_hostname" - send_stats "Host name has been changed" + echo "The hostname has been changed to:$new_hostname" + send_stats "Hostname changed" sleep 1 else - echo "Exited, hostname not changed." + echo "Exited without changing hostname." break fi done @@ -11415,30 +14005,35 @@ EOF 19) root_use - send_stats "Change the system update source" + send_stats "Change system update source" clear - echo "Select the update source area" - echo "Connect to LinuxMirrors to switch system update source" + echo "Select update source region" + echo "Access LinuxMirrors to switch system update sources" echo "------------------------" - echo "1. Mainland China [Default] 2. Mainland China [Education Network] 3. Overseas Regions" + echo "1. Mainland China [Default] 2. Mainland China [Education Network] 3. Overseas regions 4. Intelligent switching of update sources" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Enter your choice:" choice + read -e -p "Enter your selection:" choice case $choice in 1) - send_stats "Default source in mainland China" + send_stats "Mainland China default source" bash <(curl -sSL https://linuxmirrors.cn/main.sh) ;; 2) - send_stats "Source of education in mainland China" + send_stats "Mainland China Education Source" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --edu ;; 3) - send_stats "Overseas origin" + send_stats "Overseas sources" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "Intelligent switching of update sources" + switch_mirror false false + ;; + *) echo "Canceled" ;; @@ -11448,62 +14043,62 @@ EOF ;; 20) - send_stats "Timing task management" + send_stats "Scheduled task management" while true; do clear check_crontab_installed clear - echo "Timed task list" + echo "Scheduled task list" crontab -l echo "" echo "operate" echo "------------------------" - echo "1. Add timing tasks 2. Delete timing tasks 3. Edit timing tasks" + echo "1. Add a scheduled task 2. Delete a scheduled task 3. Edit a scheduled task" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - read -e -p "Please enter the execution command for the new task:" newquest + read -e -p "Please enter the execution command of the new task:" newquest echo "------------------------" - echo "1. Monthly Tasks 2. Weekly Tasks" + echo "1. Monthly tasks 2. Weekly tasks" echo "3. Daily tasks 4. Hourly tasks" echo "------------------------" - read -e -p "Please enter your selection:" dingshi + read -e -p "Please enter your choice:" dingshi case $dingshi in 1) - read -e -p "Choose what day of each month to perform tasks? (1-30):" day + read -e -p "On what day of the month do you choose to execute the task? (1-30):" day (crontab -l ; echo "0 0 $day * * $newquest") | crontab - > /dev/null 2>&1 ;; 2) - read -e -p "Choose what week to perform the task? (0-6, 0 represents Sunday):" weekday + read -e -p "Choose a day of the week to perform the task? (0-6, 0 represents Sunday):" weekday (crontab -l ; echo "0 0 * * $weekday $newquest") | crontab - > /dev/null 2>&1 ;; 3) - read -e -p "Choose what time to perform tasks every day? (Hours, 0-23):" hour + read -e -p "What time do you choose to perform the task every day? (hours, 0-23):" hour (crontab -l ; echo "0 $hour * * * $newquest") | crontab - > /dev/null 2>&1 ;; 4) - read -e -p "Enter what minute of the hour to perform the task? (mins, 0-60):" minute + read -e -p "Enter what time of the hour the task should be executed? (minutes, 0-60):" minute (crontab -l ; echo "$minute * * * * $newquest") | crontab - > /dev/null 2>&1 ;; *) break # 跳出 ;; esac - send_stats "Add timed tasks" + send_stats "Add a scheduled task" ;; 2) - read -e -p "Please enter the keywords that need to be deleted:" kquest + read -e -p "Please enter the keyword of the task to be deleted:" kquest crontab -l | grep -v "$kquest" | crontab - - send_stats "Delete timing tasks" + send_stats "Delete scheduled tasks" ;; 3) crontab -e - send_stats "Edit timing tasks" + send_stats "Edit scheduled tasks" ;; *) break # 跳出循环,退出菜单 @@ -11515,32 +14110,32 @@ EOF 21) root_use - send_stats "Local host parsing" + send_stats "Local host resolution" while true; do clear - echo "Native host parsing list" - echo "If you add parse matches here, dynamic parsing will no longer be used" + echo "Native host resolution list" + echo "If you add parsing matching here, dynamic parsing will no longer be used" cat /etc/hosts echo "" echo "operate" echo "------------------------" - echo "1. Add a new parsing 2. Delete the parsing address" + echo "1. Add new resolution 2. Delete resolution address" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" host_dns + read -e -p "Please enter your choice:" host_dns case $host_dns in 1) - read -e -p "Please enter a new parsing record Format: 110.25.5.33 kejilion.pro:" addhost + read -e -p "Please enter a new parsing record format: 110.25.5.33 kejilion.pro:" addhost echo "$addhost" >> /etc/hosts - send_stats "Local host parsing has been added" + send_stats "Local host resolution is added" ;; 2) - read -e -p "Please enter the keywords for parsing content that need to be deleted:" delhost + read -e -p "Please enter the keywords of the parsed content that need to be deleted:" delhost sed -i "/$delhost/d" /etc/hosts - send_stats "Local host parsing and deletion" + send_stats "Local host resolution and deletion" ;; *) break # 跳出循环,退出菜单 @@ -11550,109 +14145,53 @@ EOF ;; 22) - root_use - send_stats "ssh defense" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH Defense Program$check_docker" - echo "fail2ban is an SSH tool to prevent brute force" - echo "Official website introduction:${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1. Install the defense program" - echo "------------------------" - echo "2. View SSH interception records" - echo "3. Real-time log monitoring" - echo "------------------------" - echo "9. Uninstall the defense program" - echo "------------------------" - echo "0. Return to the previous menu" - echo "------------------------" - read -e -p "Please enter your selection:" sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2Ban defense program has been uninstalled" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; 23) root_use - send_stats "Current limit shutdown function" + send_stats "Current limiting shutdown function" while true; do clear - echo "Current limit shutdown function" + echo "Current limiting shutdown function" echo "Video introduction: https://www.bilibili.com/video/BV1mC411j7Qd?t=0.1" echo "------------------------------------------------" - echo "Current traffic usage, restarting the server traffic calculation will be cleared!" + echo "The current traffic usage will be cleared when the server is restarted!" output_status - echo -e "${gl_kjlan}Total Receive:${gl_bai}$rx" - echo -e "${gl_kjlan}Total send:${gl_bai}$tx" + echo -e "${gl_kjlan}Total received:${gl_bai}$rx" + echo -e "${gl_kjlan}Total sent:${gl_bai}$tx" - # Check if the Limiting_Shut_down.sh file exists + # Check if Limiting_Shut_down.sh file exists if [ -f ~/Limiting_Shut_down.sh ]; then # Get the value of threshold_gb local rx_threshold_gb=$(grep -oP 'rx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) local tx_threshold_gb=$(grep -oP 'tx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) - echo -e "${gl_lv}The current set entry-station current limit threshold is:${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" - echo -e "${gl_lv}The current outbound current limit threshold is:${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" + echo -e "${gl_lv}The currently set inbound traffic limit threshold is:${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" + echo -e "${gl_lv}The currently set outbound traffic limiting threshold is:${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" else - echo -e "${gl_hui}Current limit shutdown function is not enabled${gl_bai}" + echo -e "${gl_hui}The current limiting shutdown function is not currently enabled${gl_bai}" fi echo echo "------------------------------------------------" - echo "The system will detect whether the actual traffic reaches the threshold every minute, and the server will be automatically shut down after it arrives!" + echo "The system will detect whether the actual traffic reaches the threshold every minute, and will automatically shut down the server after reaching the threshold!" echo "------------------------" - echo "1. Turn on the current limit shutdown function 2. Deactivate the current limit shutdown function" + echo "1. Enable the current limiting shutdown function 2. Disable the current limiting shutdown function" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" Limiting + read -e -p "Please enter your choice:" Limiting case "$Limiting" in 1) - # Enter the new virtual memory size - echo "If the actual server has 100G traffic, the threshold can be set to 95G and shut down the power in advance to avoid traffic errors or overflows." - read -e -p "Please enter the incoming traffic threshold (unit is G, default is 100G):" rx_threshold_gb + # Enter new virtual memory size + echo "If the actual server only has 100G traffic, you can set the threshold to 95G and shut down in advance to avoid traffic errors or overflows." + read -e -p "Please enter the inbound traffic threshold (unit is G, default is 100G):" rx_threshold_gb rx_threshold_gb=${rx_threshold_gb:-100} read -e -p "Please enter the outbound traffic threshold (unit is G, default is 100G):" tx_threshold_gb tx_threshold_gb=${tx_threshold_gb:-100} - read -e -p "Please enter the traffic reset date (default reset on the 1st of each month):" cz_day + read -e -p "Please enter the traffic reset date (default resets on the 1st of every month):" cz_day cz_day=${cz_day:-1} cd ~ @@ -11665,15 +14204,15 @@ EOF (crontab -l ; echo "* * * * * ~/Limiting_Shut_down.sh") | crontab - > /dev/null 2>&1 crontab -l | grep -v 'reboot' | crontab - (crontab -l ; echo "0 1 $cz_day * * reboot") | crontab - > /dev/null 2>&1 - echo "Current limit shutdown has been set" - send_stats "Current limit shutdown has been set" + echo "Current limiting shutdown has been set" + send_stats "Current limiting shutdown has been set" ;; 2) check_crontab_installed crontab -l | grep -v '~/Limiting_Shut_down.sh' | crontab - crontab -l | grep -v 'reboot' | crontab - rm ~/Limiting_Shut_down.sh - echo "Current limit shutdown function has been turned off" + echo "Current limiting shutdown function is turned off" ;; *) break @@ -11692,29 +14231,29 @@ EOF echo "ROOT private key login mode" echo "Video introduction: https://www.bilibili.com/video/BV1Q4421X78n?t=209.4" echo "------------------------------------------------" - echo "A key pair will be generated, a more secure way to SSH login" + echo "A key pair will be generated, a more secure way to log in via SSH" echo "------------------------" - echo "1. Generate a new key 2. Import an existing key 3. View the native key" + echo "1. Generate a new key 2. Import an existing key 3. View the local key" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" host_dns + read -e -p "Please enter your choice:" host_dns case $host_dns in 1) - send_stats "Generate a new key" + send_stats "Generate new key" add_sshkey break_end ;; 2) - send_stats "Import an existing public key" + send_stats "Import existing public key" import_sshkey break_end ;; 3) - send_stats "View the local secret key" + send_stats "View local key" echo "------------------------" echo "Public key information" cat ~/.ssh/authorized_keys @@ -11735,18 +14274,18 @@ EOF 25) root_use - send_stats "Telegram warning" + send_stats "Telegraph warning" echo "TG-bot monitoring and early warning function" echo "Video introduction: https://youtu.be/vLL-eb3Z_TY" echo "------------------------------------------------" - echo "You need to configure the tg robot API and the user ID to receive early warnings to realize real-time monitoring and early warning of native CPU, memory, hard disk, traffic, and SSH login" - echo "After reaching the threshold, the user will be sent to the user" - echo -e "${gl_hui}- Regarding traffic, restarting the server will recalculate-${gl_bai}" - read -e -p "Are you sure to continue? (Y/N):" choice + echo "You need to configure the tg robot API and the user ID to receive alerts to achieve real-time monitoring and alerts of local CPU, memory, hard disk, traffic, and SSH login." + echo "When the threshold is reached, a warning message will be sent to the user." + echo -e "${gl_hui}- Regarding traffic, restarting the server will recalculate -${gl_bai}" + read -e -p "Are you sure you want to continue? (Y/N):" choice case "$choice" in [Yy]) - send_stats "Telegram warning is enabled" + send_stats "Telegram warning enabled" cd ~ install nano tmux bc jq check_crontab_installed @@ -11779,8 +14318,8 @@ EOF source ~/.profile clear - echo "TG-bot early warning system has been started" - echo -e "${gl_hui}You can also place the TG-check-notify.sh warning file in the root directory on other machines and use it directly!${gl_bai}" + echo "TG-bot early warning system has been activated" + echo -e "${gl_hui}You can also put the TG-check-notify.sh warning file in the root directory on other machines and use it directly!${gl_bai}" ;; [Nn]) echo "Canceled" @@ -11793,7 +14332,7 @@ EOF 26) root_use - send_stats "Fix high-risk vulnerabilities in SSH" + send_stats "Fix high-risk SSH vulnerabilities" cd ~ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/upgrade_openssh9.8p1.sh chmod +x ~/upgrade_openssh9.8p1.sh @@ -11853,90 +14392,94 @@ EOF ;; + 39) + clear + linux_fav + ;; + 41) clear - send_stats "Message board" - echo "The technology lion message board has been moved to the official community! Please leave a message in the official community!" - echo "https://bbs.kejilion.pro/" + send_stats "message board" + echo "Visit the official message board of Technology Lion. If you have any ideas about the script, please leave a message to exchange!" + echo "https://board.kejilion.pro" + echo "Public password: kejilion.sh" ;; 66) root_use send_stats "One-stop tuning" - echo "One-stop system optimization" + echo "One-stop system tuning" echo "------------------------------------------------" - echo "The following will be operated and optimized" - echo "1. Update the system to the latest" + echo "The following content will be operated and optimized" + echo "1. Optimize the system update source and update the system to the latest" echo "2. Clean up system junk files" echo -e "3. Set up virtual memory${gl_huang}1G${gl_bai}" echo -e "4. Set the SSH port number to${gl_huang}5522${gl_bai}" - echo -e "5. Open all ports" - echo -e "6. Turn on${gl_huang}BBR${gl_bai}accelerate" - echo -e "7. Set the time zone to${gl_huang}Shanghai${gl_bai}" - echo -e "8. Automatically optimize DNS address${gl_huang}Overseas: 1.1.1.1 8.8.8.8 Domestic: 223.5.5.5${gl_bai}" - echo -e "9. Install the basic tools${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10. Switch to kernel parameter optimization in Linux system${gl_huang}Balanced optimization mode${gl_bai}" + echo -e "5. Start fail2ban to defend against SSH brute force cracking" + echo -e "6. Open all ports" + echo -e "7. Turn on${gl_huang}BBR${gl_bai}accelerate" + echo -e "8. Set time zone to${gl_huang}Shanghai${gl_bai}" + echo -e "9. Automatically optimize DNS addresses${gl_huang}Overseas: 1.1.1.1 8.8.8.8 Domestic: 223.5.5.5${gl_bai}" + echo -e "10. Set the network to${gl_huang}IPv4 priority${gl_bai}" + echo -e "11. Install basic tools${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux system kernel parameter optimization switches to${gl_huang}Balanced optimization mode${gl_bai}" echo "------------------------------------------------" - read -e -p "Are you sure to have one-click maintenance? (Y/N):" choice + read -e -p "Are you sure you want one-click maintenance? (Y/N):" choice case "$choice" in [Yy]) clear - send_stats "One-stop tuning start" + send_stats "One-stop tuning starts" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10. Update the system to the latest" + echo -e "[${gl_lv}OK${gl_bai}] 1/12. Update the system to the latest" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10. Clean up system junk files" + echo -e "[${gl_lv}OK${gl_bai}] 2/12. Clean up system junk files" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10. Set up virtual memory${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 3/12. Set up virtual memory${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10. Set the SSH port number to${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 4/12. Set the SSH port number to${gl_huang}5522${gl_bai}" + echo "------------------------------------------------" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}] 5/12. Start fail2ban to defend against SSH brute force cracking" + echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10. Open all ports" + echo -e "[${gl_lv}OK${gl_bai}] 6/12. Open all ports" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10. Open${gl_huang}BBR${gl_bai}accelerate" + echo -e "[${gl_lv}OK${gl_bai}] 7/12. Open${gl_huang}BBR${gl_bai}accelerate" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10. Set the time zone to${gl_huang}Shanghai${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 8/12. Set time zone to${gl_huang}Shanghai${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10. Automatically optimize DNS address${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}] 9/12. Automatically optimize DNS address${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}] 10/12. Set the network to${gl_huang}IPv4 priority${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10. Install the basic tools${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 11/12. Install basic tools${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10. Optimization of kernel parameters for Linux system" + echo -e "[${gl_lv}OK${gl_bai}] 12/12. Linux system kernel parameter optimization" echo -e "${gl_lv}One-stop system tuning has been completed${gl_bai}" ;; @@ -11961,39 +14504,39 @@ EOF while true; do clear if grep -q '^ENABLE_STATS="true"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_lv}正在采集数据${gl_bai}" + local status_message="${gl_lv}Collecting data${gl_bai}" elif grep -q '^ENABLE_STATS="false"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_hui}采集已关闭${gl_bai}" + local status_message="${gl_hui}Collection is closed${gl_bai}" else - local status_message="无法确定的状态" + local status_message="Uncertain status" fi - echo "Privacy and Security" - echo "The script will collect data on user functions, optimize the script experience, and create more fun and useful functions." - echo "Will collect the script version number, usage time, system version, CPU architecture, country of the machine and the name of the function used," + echo "Privacy and security" + echo "The script will collect data on users’ use of functions, optimize the script experience, and create more fun and useful functions." + echo "The script version number, time of use, system version, CPU architecture, country of the machine and name of the function used will be collected," echo "------------------------------------------------" echo -e "Current status:$status_message" echo "--------------------" - echo "1. Turn on collection" - echo "2. Close the collection" + echo "1. Start collection" + echo "2. Close collection" echo "--------------------" echo "0. Return to the previous menu" echo "--------------------" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) cd ~ sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' ~/kejilion.sh - echo "Collection has been enabled" - send_stats "Privacy and security collection has been enabled" + echo "Collection has been started" + send_stats "Privacy and security collection has been turned on" ;; 2) cd ~ sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' ~/kejilion.sh echo "Collection closed" - send_stats "Privacy and Security have been closed for collection" + send_stats "Privacy and security collection has been turned off" ;; *) break @@ -12012,8 +14555,8 @@ EOF send_stats "Uninstall tech lion script" echo "Uninstall tech lion script" echo "------------------------------------------------" - echo "Will completely uninstall the kejilion script and will not affect your other functions" - read -e -p "Are you sure to continue? (Y/N):" choice + echo "The kejilion script will be completely uninstalled without affecting your other functions." + read -e -p "Are you sure you want to continue? (Y/N):" choice case "$choice" in [Yy]) @@ -12021,7 +14564,7 @@ EOF (crontab -l | grep -v "kejilion.sh") | crontab - rm -f /usr/local/bin/k rm ~/kejilion.sh - echo "The script has been uninstalled, goodbye!" + echo "The script has been uninstalled, bye!" break_end clear exit @@ -12058,87 +14601,87 @@ EOF linux_file() { root_use - send_stats "File Manager" + send_stats "file manager" while true; do clear - echo "File Manager" + echo "file manager" echo "------------------------" - echo "Current path" + echo "current path" pwd echo "------------------------" ls --color=auto -x echo "------------------------" - echo "1. Enter the directory 2. Create the directory 3. Modify the directory permissions 4. Rename the directory" + echo "1. Enter the directory 2. Create the directory 3. Modify directory permissions 4. Rename the directory" echo "5. Delete the directory 6. Return to the previous menu directory" echo "------------------------" - echo "11. Create a file 12. Edit a file 13. Modify file permissions 14. Rename a file" - echo "15. Delete the file" + echo "11. Create files 12. Edit files 13. Modify file permissions 14. Rename files" + echo "15. Delete files" echo "------------------------" echo "21. Compress file directory 22. Unzip file directory 23. Move file directory 24. Copy file directory" - echo "25. Pass the file to another server" + echo "25. Transfer files to other servers" echo "------------------------" echo "0. Return to the previous menu" echo "------------------------" - read -e -p "Please enter your selection:" Limiting + read -e -p "Please enter your choice:" Limiting case "$Limiting" in 1) # 进入目录 read -e -p "Please enter the directory name:" dirname - cd "$dirname" 2>/dev/null || echo "Unable to enter the directory" - send_stats "Go to the directory" + cd "$dirname" 2>/dev/null || echo "Unable to enter directory" + send_stats "Enter directory" ;; 2) # 创建目录 - read -e -p "Please enter the directory name to create:" dirname + read -e -p "Please enter the directory name to be created:" dirname mkdir -p "$dirname" && echo "Directory created" || echo "Creation failed" - send_stats "Create a directory" + send_stats "Create directory" ;; 3) # 修改目录权限 read -e -p "Please enter the directory name:" dirname - read -e -p "Please enter permissions (such as 755):" perm + read -e -p "Please enter permissions (e.g. 755):" perm chmod "$perm" "$dirname" && echo "Permissions have been modified" || echo "Modification failed" send_stats "Modify directory permissions" ;; 4) # 重命名目录 read -e -p "Please enter the current directory name:" current_name - read -e -p "Please enter the new directory name:" new_name + read -e -p "Please enter a new directory name:" new_name mv "$current_name" "$new_name" && echo "Directory has been renamed" || echo "Rename failed" - send_stats "Rename the directory" + send_stats "Rename directory" ;; 5) # 删除目录 - read -e -p "Please enter the directory name to delete:" dirname - rm -rf "$dirname" && echo "Directory has been deleted" || echo "Deletion failed" - send_stats "Delete Directory" + read -e -p "Please enter the directory name to be deleted:" dirname + rm -rf "$dirname" && echo "Directory deleted" || echo "Delete failed" + send_stats "delete directory" ;; 6) # 返回上一级选单目录 cd .. send_stats "Return to the previous menu directory" ;; 11) # 创建文件 - read -e -p "Please enter the file name to create:" filename + read -e -p "Please enter the file name to be created:" filename touch "$filename" && echo "File created" || echo "Creation failed" - send_stats "Create a file" + send_stats "Create file" ;; 12) # 编辑文件 - read -e -p "Please enter the file name to edit:" filename + read -e -p "Please enter the file name to be edited:" filename install nano nano "$filename" - send_stats "Edit files" + send_stats "Edit file" ;; 13) # 修改文件权限 - read -e -p "Please enter the file name:" filename - read -e -p "Please enter permissions (such as 755):" perm + read -e -p "Please enter a file name:" filename + read -e -p "Please enter permissions (e.g. 755):" perm chmod "$perm" "$filename" && echo "Permissions have been modified" || echo "Modification failed" send_stats "Modify file permissions" ;; 14) # 重命名文件 read -e -p "Please enter the current file name:" current_name read -e -p "Please enter a new file name:" new_name - mv "$current_name" "$new_name" && echo "File renamed" || echo "Rename failed" - send_stats "Rename the file" + mv "$current_name" "$new_name" && echo "File has been renamed" || echo "Rename failed" + send_stats "Rename file" ;; 15) # 删除文件 - read -e -p "Please enter the file name to delete:" filename - rm -f "$filename" && echo "File deleted" || echo "Deletion failed" + read -e -p "Please enter the file name to be deleted:" filename + rm -f "$filename" && echo "File deleted" || echo "Delete failed" send_stats "Delete files" ;; 21) # 压缩文件/目录 @@ -12148,65 +14691,65 @@ linux_file() { send_stats "Compressed files/directories" ;; 22) # 解压文件/目录 - read -e -p "Please enter the file name (.tar.gz):" filename + read -e -p "Please enter the file name to be extracted (.tar.gz):" filename install tar - tar -xzvf "$filename" && echo "Decompressed$filename" || echo "Decompression failed" + tar -xzvf "$filename" && echo "Unzipped$filename" || echo "Decompression failed" send_stats "Unzip files/directories" ;; 23) # 移动文件或目录 - read -e -p "Please enter the file or directory path to move:" src_path + read -e -p "Please enter the file or directory path to be moved:" src_path if [ ! -e "$src_path" ]; then - echo "Error: The file or directory does not exist." - send_stats "Failed to move a file or directory: The file or directory does not exist" + echo "Error: File or directory does not exist." + send_stats "Failed to move file or directory: File or directory does not exist" continue fi - read -e -p "Please enter the target path (including the new file name or directory name):" dest_path + read -e -p "Please enter the destination path (including new file or directory name):" dest_path if [ -z "$dest_path" ]; then - echo "Error: Please enter the target path." - send_stats "Moving file or directory failed: The destination path is not specified" + echo "Error: Please enter destination path." + send_stats "Failed to move file or directory: Destination path not specified" continue fi - mv "$src_path" "$dest_path" && echo "The file or directory has been moved to$dest_path" || echo "Failed to move files or directories" - send_stats "Move files or directories" + mv "$src_path" "$dest_path" && echo "File or directory moved to$dest_path" || echo "Failed to move file or directory" + send_stats "Move a file or directory" ;; 24) # 复制文件目录 read -e -p "Please enter the file or directory path to copy:" src_path if [ ! -e "$src_path" ]; then - echo "Error: The file or directory does not exist." - send_stats "Failed to copy a file or directory: The file or directory does not exist" + echo "Error: File or directory does not exist." + send_stats "Copying file or directory failed: File or directory does not exist" continue fi - read -e -p "Please enter the target path (including the new file name or directory name):" dest_path + read -e -p "Please enter the destination path (including new file or directory name):" dest_path if [ -z "$dest_path" ]; then - echo "Error: Please enter the target path." - send_stats "Failed to copy file or directory: Destination path not specified" + echo "Error: Please enter destination path." + send_stats "Copying file or directory failed: Destination path not specified" continue fi - # Use the -r option to copy the directory recursively - cp -r "$src_path" "$dest_path" && echo "The file or directory has been copied to$dest_path" || echo "Failed to copy a file or directory" - send_stats "Copy files or directories" + # Use the -r option to copy directories recursively + cp -r "$src_path" "$dest_path" && echo "File or directory copied to$dest_path" || echo "Failed to copy file or directory" + send_stats "Copy a file or directory" ;; 25) # 传送文件至远端服务器 read -e -p "Please enter the file path to be transferred:" file_to_transfer if [ ! -f "$file_to_transfer" ]; then - echo "Error: The file does not exist." - send_stats "Failed to transfer the file: The file does not exist" + echo "Error: File does not exist." + send_stats "Failed to transfer file: file does not exist" continue fi read -e -p "Please enter the remote server IP:" remote_ip if [ -z "$remote_ip" ]; then echo "Error: Please enter the remote server IP." - send_stats "File transfer failed: Remote server IP was not entered" + send_stats "File transfer failed: Remote server IP not entered" continue fi @@ -12235,7 +14778,7 @@ EOF if [ $? -eq 0 ]; then echo "The file has been transferred to the remote server home directory." - send_stats "File transfer successfully" + send_stats "File transfer successful" else echo "File transfer failed." send_stats "File transfer failed" @@ -12247,7 +14790,7 @@ EOF 0) # 返回上一级选单 - send_stats "Return to the previous menu menu" + send_stats "Return to the previous menu" break ;; *) # 处理无效输入 @@ -12278,10 +14821,10 @@ run_commands_on_servers() { local SERVERS_FILE="$HOME/cluster/servers.py" local SERVERS=$(grep -oP '{"name": "\K[^"]+|"hostname": "\K[^"]+|"port": \K[^,]+|"username": "\K[^"]+|"password": "\K[^"]+' "$SERVERS_FILE") - # Convert extracted information into an array + # Convert the extracted information into an array IFS=$'\n' read -r -d '' -a SERVER_ARRAY <<< "$SERVERS" - # Iterate through the server and execute commands + # Traverse the server and execute commands for ((i=0; i<${#SERVER_ARRAY[@]}; i+=5)); do local name=${SERVER_ARRAY[i]} local hostname=${SERVER_ARRAY[i+1]} @@ -12311,30 +14854,30 @@ fi while true; do clear - send_stats "Cluster Control Center" + send_stats "Cluster control center" echo "Server cluster control" cat ~/cluster/servers.py echo echo -e "${gl_kjlan}------------------------${gl_bai}" - echo -e "${gl_kjlan}Server List Management${gl_bai}" - echo -e "${gl_kjlan}1. ${gl_bai}Add a server${gl_kjlan}2. ${gl_bai}Delete the server${gl_kjlan}3. ${gl_bai}Edit the server" - echo -e "${gl_kjlan}4. ${gl_bai}Backup cluster${gl_kjlan}5. ${gl_bai}Restore the cluster" + echo -e "${gl_kjlan}Server list management${gl_bai}" + echo -e "${gl_kjlan}1. ${gl_bai}Add server${gl_kjlan}2. ${gl_bai}Delete server${gl_kjlan}3. ${gl_bai}Edit server" + echo -e "${gl_kjlan}4. ${gl_bai}Backup cluster${gl_kjlan}5. ${gl_bai}Restore cluster" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}Execute tasks in batches${gl_bai}" - echo -e "${gl_kjlan}11. ${gl_bai}Install the tech lion script${gl_kjlan}12. ${gl_bai}Update the system${gl_kjlan}13. ${gl_bai}Clean the system" - echo -e "${gl_kjlan}14. ${gl_bai}Install docker${gl_kjlan}15. ${gl_bai}Install BBR3${gl_kjlan}16. ${gl_bai}Set up 1G virtual memory" - echo -e "${gl_kjlan}17. ${gl_bai}Set the time zone to Shanghai${gl_kjlan}18. ${gl_bai}Open all ports${gl_kjlan}51. ${gl_bai}Custom commands" + echo -e "${gl_kjlan}11. ${gl_bai}Install technology lion script${gl_kjlan}12. ${gl_bai}Update system${gl_kjlan}13. ${gl_bai}Clean the system" + echo -e "${gl_kjlan}14. ${gl_bai}Install docker${gl_kjlan}15. ${gl_bai}Install BBR3${gl_kjlan}16. ${gl_bai}Set 1G virtual memory" + echo -e "${gl_kjlan}17. ${gl_bai}Set time zone to Shanghai${gl_kjlan}18. ${gl_bai}Open all ports${gl_kjlan}51. ${gl_bai}custom directive" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "Please enter your selection:" sub_choice + read -e -p "Please enter your choice:" sub_choice case $sub_choice in 1) - send_stats "Add a cluster server" + send_stats "Add cluster server" read -e -p "Server name:" server_name read -e -p "Server IP:" server_ip - read -e -p "Server Port (22):" server_port + read -e -p "Server port (22):" server_port local server_port=${server_port:-22} read -e -p "Server username (root):" server_username local server_username=${server_username:-root} @@ -12344,12 +14887,12 @@ while true; do ;; 2) - send_stats "Delete the cluster server" - read -e -p "Please enter the keywords you need to delete:" rmserver + send_stats "Delete cluster server" + read -e -p "Please enter the keywords to be deleted:" rmserver sed -i "/$rmserver/d" ~/cluster/servers.py ;; 3) - send_stats "Edit the cluster server" + send_stats "Edit cluster server" install nano nano ~/cluster/servers.py ;; @@ -12357,15 +14900,15 @@ while true; do 4) clear send_stats "Backup cluster" - echo -e "Please${gl_huang}/root/cluster/servers.py${gl_bai}Download the file and complete the backup!" + echo -e "please change${gl_huang}/root/cluster/servers.py${gl_bai}Download the file and complete the backup!" break_end ;; 5) clear - send_stats "Restore the cluster" + send_stats "Restore cluster" echo "Please upload your servers.py and press any key to start uploading!" - echo -e "Please upload your${gl_huang}servers.py${gl_bai}File to${gl_huang}/root/cluster/${gl_bai}Complete the restore!" + echo -e "Please upload your${gl_huang}servers.py${gl_bai}file to${gl_huang}/root/cluster/${gl_bai}Restore completed!" break_end ;; @@ -12396,8 +14939,8 @@ while true; do ;; 51) - send_stats "Customize the execution of commands" - read -e -p "Please enter the batch execution command:" mingling + send_stats "Custom execution command" + read -e -p "Please enter the command for batch execution:" mingling run_commands_on_servers "${mingling}" ;; @@ -12420,39 +14963,39 @@ echo "Advertising column" echo "------------------------" echo "It will provide users with a simpler and more elegant promotion and purchasing experience!" echo "" -echo -e "Server Offers" +echo -e "Server Discount" echo "------------------------" -echo -e "${gl_lan}Leica Cloud Hong Kong CN2 GIA South Korea Dual ISP US CN2 GIA Discounts${gl_bai}" +echo -e "${gl_lan}Laika Cloud Hong Kong CN2 GIA Korean dual ISP US CN2 GIA promotions${gl_bai}" echo -e "${gl_bai}Website: https://www.lcayun.com/aff/ZEXUQBIM${gl_bai}" echo "------------------------" -echo -e "${gl_lan}RackNerd $10.99 per year United States 1 core 1G memory 20G hard drive 1T traffic per month${gl_bai}" -echo -e "${gl_bai}Website: https://my.racknerd.com/aff.php?aff=5501&pid=879${gl_bai}" +echo -e "${gl_lan}RackNerd $10.99 per year, USA, 1 core, 1G memory, 20G hard drive, 1T traffic per month${gl_bai}" +echo -e "${gl_bai}URL: https://my.racknerd.com/aff.php?aff=5501&pid=879${gl_bai}" echo "------------------------" -echo -e "${gl_zi}Hostinger 52.7 dollars per year United States 1 core 4G memory 50G hard drive 4T traffic per month${gl_bai}" -echo -e "${gl_bai}Website: https://cart.hostinger.com/pay/d83c51e9-0c28-47a6-8414-b8ab010ef94f?_ga=GA1.3.942352702.1711283207${gl_bai}" +echo -e "${gl_zi}Hostinger $52.7 per year United States 1 core 4G memory 50G hard drive 4T traffic per month${gl_bai}" +echo -e "${gl_bai}URL: https://cart.hostinger.com/pay/d83c51e9-0c28-47a6-8414-b8ab010ef94f?_ga=GA1.3.942352702.1711283207${gl_bai}" echo "------------------------" -echo -e "${gl_huang}Brickworker, $49 per quarter, US CN2GIA, Japan SoftBank, 2 cores, 1G memory, 20G hard drive, 1T traffic per month${gl_bai}" +echo -e "${gl_huang}Bricklayer 49 dollars per quarter US CN2GIA Japan SoftBank 2 cores 1G memory 20G hard drive 1T traffic per month${gl_bai}" echo -e "${gl_bai}Website: https://bandwagonhost.com/aff.php?aff=69004&pid=87${gl_bai}" echo "------------------------" echo -e "${gl_lan}DMIT $28 per quarter US CN2GIA 1 core 2G memory 20G hard drive 800G traffic per month${gl_bai}" -echo -e "${gl_bai}Website: https://www.dmit.io/aff.php?aff=4966&pid=100${gl_bai}" +echo -e "${gl_bai}URL: https://www.dmit.io/aff.php?aff=4966&pid=100${gl_bai}" echo "------------------------" -echo -e "${gl_zi}V.PS $6.9 per month Tokyo SoftBank 2 core 1G memory 20G hard drive 1T traffic per month${gl_bai}" -echo -e "${gl_bai}Website: https://vps.hosting/cart/tokyo-cloud-kvm-vps/?id=148&?affid=1355&?affid=1355${gl_bai}" +echo -e "${gl_zi}V.PS 6.9 dollars per month Tokyo Softbank 2 cores 1G memory 20G hard drive 1T traffic per month${gl_bai}" +echo -e "${gl_bai}URL: https://vps.hosting/cart/tokyo-cloud-kvm-vps/?id=148&?affid=1355&?affid=1355${gl_bai}" echo "------------------------" -echo -e "${gl_kjlan}More popular VPS offers${gl_bai}" +echo -e "${gl_kjlan}More popular VPS deals${gl_bai}" echo -e "${gl_bai}Website: https://kejilion.pro/topvps/${gl_bai}" echo "------------------------" echo "" echo -e "Domain name discount" echo "------------------------" -echo -e "${gl_lan}GNAME 8.8 dollars first year COM domain name 6.68 dollars first year CC domain name${gl_bai}" +echo -e "${gl_lan}GNAME $8.8 first-year COM domain name $6.68 first-year CC domain name${gl_bai}" echo -e "${gl_bai}Website: https://www.gname.com/register?tt=86836&ttcode=KEJILION86836&ttbj=sh${gl_bai}" echo "------------------------" echo "" -echo -e "Technology lion surrounding" +echo -e "Technology lion peripherals" echo "------------------------" -echo -e "${gl_kjlan}B station:${gl_bai}https://b23.tv/2mqnQyh ${gl_kjlan}Oil pipe:${gl_bai}https://www.youtube.com/@kejilion${gl_bai}" +echo -e "${gl_kjlan}Station B:${gl_bai}https://b23.tv/2mqnQyh ${gl_kjlan}Oil pipe:${gl_bai}https://www.youtube.com/@kejilion${gl_bai}" echo -e "${gl_kjlan}Official website:${gl_bai}https://kejilion.pro/ ${gl_kjlan}navigation:${gl_bai}https://dh.kejilion.pro/${gl_bai}" echo -e "${gl_kjlan}blog:${gl_bai}https://blog.kejilion.pro/ ${gl_kjlan}Software Center:${gl_bai}https://app.kejilion.pro/${gl_bai}" echo "------------------------" @@ -12464,6 +15007,64 @@ echo "" +games_server_tools() { + + while true; do + clear + echo -e "Collection of game server opening scripts" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}Eudemons Parlu server opening script" + echo -e "${gl_kjlan}2. ${gl_bai}Minecraft server opening script" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}Return to main menu" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "Please enter your choice:" sub_choice + + case $sub_choice in + + 1) send_stats "Eudemons Parlu server opening script" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh + exit + ;; + 2) send_stats "Minecraft server opening script" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/mc.sh ; chmod +x mc.sh ; ./mc.sh + exit + ;; + + 0) + kejilion + ;; + + *) + echo "Invalid input!" + ;; + esac + break_end + + done + + +} + + + + + + + + + + + + + + + + + + + + kejilion_update() { @@ -12471,7 +15072,7 @@ send_stats "Script update" cd ~ while true; do clear - echo "Update log" + echo "Change log" echo "------------------------" echo "All logs:${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/kejilion_sh_log.txt" echo "------------------------" @@ -12480,11 +15081,11 @@ while true; do local sh_v_new=$(curl -s ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/kejilion.sh | grep -o 'sh_v="[0-9.]*"' | cut -d '"' -f 2) if [ "$sh_v" = "$sh_v_new" ]; then - echo -e "${gl_lv}You are already the latest version!${gl_huang}v$sh_v${gl_bai}" - send_stats "The script is up to date and no update is required" + echo -e "${gl_lv}You are already on the latest version!${gl_huang}v$sh_v${gl_bai}" + send_stats "The script is already up to date and does not need to be updated" else - echo "Discover a new version!" - echo -e "Current version v$sh_vLatest version${gl_huang}v$sh_v_new${gl_bai}" + echo "New version discovered!" + echo -e "Current version v$sh_vlatest version${gl_huang}v$sh_v_new${gl_bai}" fi @@ -12493,15 +15094,15 @@ while true; do if [ -n "$existing_cron" ]; then echo "------------------------" - echo -e "${gl_lv}Automatic update is enabled, and the script will be automatically updated at 2 a.m. every day!${gl_bai}" + echo -e "${gl_lv}Automatic updates are turned on, and the script will be automatically updated at 2 a.m. every day!${gl_bai}" fi echo "------------------------" - echo "1. Update now 2. Turn on automatic update 3. Turn off automatic update" + echo "1. Update now 2. Turn on automatic updates 3. Turn off automatic updates" echo "------------------------" echo "0. Return to main menu" echo "------------------------" - read -e -p "Please enter your selection:" choice + read -e -p "Please enter your choice:" choice case "$choice" in 1) clear @@ -12536,15 +15137,15 @@ while true; do (crontab -l | grep -v "kejilion.sh") | crontab - # (crontab -l 2>/dev/null; echo "0 2 * * * bash -c \"$SH_Update_task\"") | crontab - (crontab -l 2>/dev/null; echo "$(shuf -i 0-59 -n 1) 2 * * * bash -c \"$SH_Update_task\"") | crontab - - echo -e "${gl_lv}Automatic update is enabled, and the script will be automatically updated at 2 a.m. every day!${gl_bai}" - send_stats "Turn on automatic script update" + echo -e "${gl_lv}Automatic updates are turned on, and the script will be automatically updated at 2 a.m. every day!${gl_bai}" + send_stats "Enable automatic script updates" break_end ;; 3) clear (crontab -l | grep -v "kejilion.sh") | crontab - - echo -e "${gl_lv}Automatic update is closed${gl_bai}" - send_stats "Close script automatic update" + echo -e "${gl_lv}Automatic updates are turned off${gl_bai}" + send_stats "Turn off automatic script updates" break_end ;; *) @@ -12567,36 +15168,35 @@ echo "╦╔═╔═╗ ╦╦╦ ╦╔═╗╔╗╔ ╔═╗╦ ╦" echo "╠╩╗║╣ ║║║ ║║ ║║║║ ╚═╗╠═╣" echo "╩ ╩╚═╝╚╝╩╩═╝╩╚═╝╝╚╝o╚═╝╩ ╩" echo -e "Technology lion script toolbox v$sh_v" -echo -e "Command line input${gl_huang}k${gl_kjlan}Quickly start scripts${gl_bai}" +echo -e "Command line input${gl_huang}k${gl_kjlan}Quick start script${gl_bai}" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}1. ${gl_bai}System information query" echo -e "${gl_kjlan}2. ${gl_bai}System update" -echo -e "${gl_kjlan}3. ${gl_bai}System Cleanup" -echo -e "${gl_kjlan}4. ${gl_bai}Basic tools" -echo -e "${gl_kjlan}5. ${gl_bai}BBR Management" -echo -e "${gl_kjlan}6. ${gl_bai}Docker Management" -echo -e "${gl_kjlan}7. ${gl_bai}WARP Management" +echo -e "${gl_kjlan}3. ${gl_bai}System cleanup" +echo -e "${gl_kjlan}4. ${gl_bai}basic tools" +echo -e "${gl_kjlan}5. ${gl_bai}BBR management" +echo -e "${gl_kjlan}6. ${gl_bai}Docker management" +echo -e "${gl_kjlan}7. ${gl_bai}WARP management" echo -e "${gl_kjlan}8. ${gl_bai}Test script collection" echo -e "${gl_kjlan}9. ${gl_bai}Oracle Cloud Script Collection" echo -e "${gl_huang}10. ${gl_bai}LDNMP website building" -echo -e "${gl_kjlan}11. ${gl_bai}Application Market" +echo -e "${gl_kjlan}11. ${gl_bai}application market" echo -e "${gl_kjlan}12. ${gl_bai}Backend workspace" -echo -e "${gl_kjlan}13. ${gl_bai}System Tools" +echo -e "${gl_kjlan}13. ${gl_bai}system tools" echo -e "${gl_kjlan}14. ${gl_bai}Server cluster control" echo -e "${gl_kjlan}15. ${gl_bai}Advertising column" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}Phantom Beast Palu server opening script" +echo -e "${gl_kjlan}16. ${gl_bai}Collection of game server opening scripts" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}Script update" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}0. ${gl_bai}Exit script" echo -e "${gl_kjlan}------------------------${gl_bai}" -read -e -p "Please enter your selection:" choice +read -e -p "Please enter your choice:" choice case $choice in - 1) linux_ps ;; + 1) linux_info ;; 2) clear ; send_stats "System update" ; linux_update ;; - 3) clear ; send_stats "System Cleanup" ; linux_clean ;; + 3) clear ; send_stats "System cleanup" ; linux_clean ;; 4) linux_tools ;; 5) linux_bbr ;; 6) linux_docker ;; @@ -12611,10 +15211,7 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "Phantom Beast Palu server opening script" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; *) echo "Invalid input!" ;; @@ -12625,55 +15222,60 @@ done k_info() { -send_stats "k command reference use case" +send_stats "k command reference examples" echo "-------------------" echo "Video introduction: https://www.bilibili.com/video/BV1ib421E7it?t=0.1" -echo "The following is the k command reference use case:" +echo "The following is a reference use case for the k command:" echo "Start script k" -echo "Install software package k install nano wget | k add nano wget | k Install nano wget" -echo "Uninstall the package k remove nano wget | k del nano wget | k uninstall nano wget | k Uninstall nano wget" +echo "Install packages k install nano wget | k add nano wget | k install nano wget" +echo "Uninstall a package k remove nano wget | k del nano wget | k uninstall nano wget | k uninstall nano wget" echo "Update system k update | k update" -echo "Clean system garbage k clean | k clean" -echo "Reinstall the system panel k dd | k Reinstall" +echo "Clean system junk k clean | k clean" +echo "Reinstall the system panel k dd | k reinstall" echo "bbr3 control panel k bbr3 | k bbrv3" -echo "Kernel Tuning Panel k nhyh | k kernel optimization" +echo "Kernel Tuning Panel k nhyh | k Kernel Optimization" echo "Set virtual memory k swap 2048" echo "Set virtual time zone k time Asia/Shanghai | k time zone Asia/Shanghai" -echo "System Recycling Bin k trash | k hsz | k Recycling Bin" +echo "System Recycle Bin k trash | k hsz | k Recycle Bin" echo "System backup function k backup | k bf | k backup" echo "ssh remote connection tool k ssh | k remote connection" echo "rsync remote synchronization tool k rsync | k remote synchronization" echo "Hard disk management tool k disk | k hard disk management" -echo "Intranet penetration (server side) k frps" +echo "Intranet penetration (server) k frps" echo "Intranet penetration (client) k frpc" -echo "Software start k start sshd | k start sshd" +echo "Software startup k start sshd | k start sshd" echo "Software stop k stop sshd | k stop sshd" echo "Software restart k restart sshd | k restart sshd" -echo "Software status view k status sshd | k status sshd" -echo "Software boot k enable docker | k autostart docke | k startup docker" +echo "Check software status k status sshd | k status sshd" +echo "k enable docker | k autostart docker | k enable docker when booting the software" echo "Domain name certificate application k ssl" -echo "Domain name certificate expiration query k ssl ps" +echo "Domain name certificate expiry query k ssl ps" +echo "docker management plane k docker" echo "docker environment installation k docker install |k docker installation" echo "docker container management k docker ps |k docker container" echo "docker image management k docker img |k docker image" echo "LDNMP site management k web" -echo "LDNMP cache cleanup k web cache" -echo "Install WordPress k wp |k wordpress |k wp xxx.com" -echo "Install the reverse proxy k fd |k rp |k anti-generation |k fd xxx.com" +echo "LDNMP cache cleaning k web cache" +echo "安装WordPress k wp |k wordpress |k wp xxx.com" +echo "Install reverse proxy k fd |k rp |k reverse proxy |k fd xxx.com" echo "Install load balancing k loadbalance |k load balancing" -echo "Firewall panel k fhq |k firewall" -echo "Open port k dkdk 8080 |k Open port 8080" +echo "Install L4 load balancing k stream |k L4 load balancing" +echo "firewall panel k fhq |k firewall" +echo "open port k dkdk 8080 |k open port 8080" echo "Close port k gbdk 7800 |k Close port 7800" -echo "放行IP k fxip 127.0.0.0/8 |k 放行IP 127.0.0.0/8" +echo "Release IP k fxip 127.0.0.0/8 |k Release IP 127.0.0.0/8" echo "Block IP k zzip 177.5.25.36 |k Block IP 177.5.25.36" - - +echo "command favorites k fav | k command favorites" +echo "Application market management k app" +echo "Quick management of application numbers k app 26 | k app 1panel | k app npm" +echo "fail2ban management k fail2ban | k f2b" +echo "Display system information k info" } if [ "$#" -eq 0 ]; then - # If there are no parameters, run interactive logic + # Without arguments, run interactive logic kejilion_sh else # If there are parameters, execute the corresponding function @@ -12685,7 +15287,7 @@ else ;; remove|del|uninstall|卸载) shift - send_stats "Uninstall the software" + send_stats "Uninstall software" remove "$@" ;; update|更新) @@ -12719,7 +15321,7 @@ else rsync_run) shift - send_stats "Timed rsync synchronization" + send_stats "Scheduled rsync synchronization" run_task "$@" ;; @@ -12738,7 +15340,7 @@ else find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ ports have been blocked from accessing the service" + echo "IP+port has been blocked from accessing the service" else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -12749,6 +15351,11 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift send_stats "Quickly set up virtual memory" @@ -12799,9 +15406,13 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift - send_stats "Software status view" + send_stats "Check software status" status "$@" ;; start|启动) @@ -12811,7 +15422,7 @@ else ;; stop|停止) shift - send_stats "Software pause" + send_stats "software pause" stop "$@" ;; restart|重启) @@ -12822,21 +15433,21 @@ else enable|autostart|开机启动) shift - send_stats "Software boots up" + send_stats "Software starts automatically when booting" enable "$@" ;; ssl) shift if [ "$1" = "ps" ]; then - send_stats "Check the certificate status" + send_stats "View certificate status" ssl_ps elif [ -z "$1" ]; then add_ssl - send_stats "Quickly apply for a certificate" + send_stats "Apply for a certificate quickly" elif [ -n "$1" ]; then add_ssl "$1" - send_stats "Quickly apply for a certificate" + send_stats "Apply for a certificate quickly" else k_info fi @@ -12854,11 +15465,11 @@ else docker_ps ;; img|镜像) - send_stats "Quick mirror management" + send_stats "Quick image management" docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -12878,6 +15489,22 @@ else fi ;; + + app) + shift + send_stats "Apply$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/jp/kejilion.sh b/jp/kejilion.sh index 89c7f4814..634379b25 100644 --- a/jp/kejilion.sh +++ b/jp/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.3" +sh_v="4.3.1" gl_hui='\e[37m' @@ -34,7 +34,7 @@ quanju_canshu -# コマンドを実行する関数を定義します +# コマンドを実行する関数を定義する run_command() { if [ "$zhushi" -eq 0 ]; then "$@" @@ -57,9 +57,9 @@ CheckFirstRun_true() { -# 関数の埋もポイント情報を収集し、現在のスクリプトバージョン番号、使用時間、システムバージョン、CPUアーキテクチャ、マシンの国、ユーザーが使用する関数名を記録する関数。彼らは絶対に機密情報を伴わない、安心してください!私を信じてください! -# なぜこの関数を設計する必要があるのですか?目的は、ユーザーが使用する機能をよりよく理解し、関数をさらに最適化して、ユーザーのニーズを満たすより多くの関数を起動することです。 -# 全文の場合、send_stats関数の呼び出し場所、透明性、オープンソースを検索できます。懸念がある場合は、使用を拒否できます。 +# この機能は、機能の埋め込み情報を収集し、現在のスクリプトのバージョン番号、使用時間、システム バージョン、CPU アーキテクチャ、マシンの国、およびユーザーが使用した機能名を記録します。機密情報は含まれませんので、ご安心ください。信じてください! +# なぜこの機能が設計されたのでしょうか?その目的は、ユーザーが使いたい機能をより深く理解し、機能をさらに最適化し、ユーザーのニーズを満たす機能をさらに投入することです。 +# send_stats 関数の呼び出し位置を全文検索できます。これは透明性があり、オープンソースです。ご心配な場合はご利用をお断りすることも可能です。 @@ -111,22 +111,22 @@ CheckFirstRun_false() { fi } -# ユーザーに条件に同意するように促します +# ユーザーに規約への同意を求めるプロンプトを表示する UserLicenseAgreement() { clear - echo -e "${gl_kjlan}Tech Lion Script Toolboxへようこそ${gl_bai}" - echo "スクリプトを初めて使用して、ユーザーライセンス契約を読んで同意してください。" - echo "ユーザーライセンス契約:https://blog.kejilion.pro/user-license-agreement/" + echo -e "${gl_kjlan}テクノロジー ライオン スクリプト ツールボックスへようこそ${gl_bai}" + echo "初めてスクリプトを使用する場合は、ユーザー使用許諾契約を読み、同意してください。" + echo "ユーザー使用許諾契約書: https://blog.kejilion.pro/user-license-agreement/" echo -e "----------------------" - read -r -p "上記の条件に同意しますか? (y/n):" user_input + read -r -p "上記の条件に同意しますか? (y/n):" user_input if [ "$user_input" = "y" ] || [ "$user_input" = "Y" ]; then - send_stats "ライセンスの同意" + send_stats "ライセンス契約" sed -i 's/^permission_granted="false"/permission_granted="true"/' ~/kejilion.sh sed -i 's/^permission_granted="false"/permission_granted="true"/' /usr/local/bin/k else - send_stats "許可の拒否" + send_stats "許可が拒否されました" clear exit fi @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -170,13 +170,13 @@ ipv6_address=$(curl -s --max-time 1 https://v6.ipinfo.io/ip && echo) install() { if [ $# -eq 0 ]; then - echo "パッケージパラメーターは提供されていません!" + echo "パッケージパラメータが指定されていません!" return 1 fi for package in "$@"; do if ! command -v "$package" &>/dev/null; then - echo -e "${gl_huang}インストール$package...${gl_bai}" + echo -e "${gl_huang}インストール中$package...${gl_bai}" if command -v dnf &>/dev/null; then dnf -y update dnf install -y epel-release @@ -204,7 +204,7 @@ install() { pkg update pkg install -y "$package" else - echo "不明なパッケージマネージャー!" + echo "不明なパッケージマネージャーです!" return 1 fi fi @@ -213,35 +213,45 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then - echo -e "${gl_huang}ヒント:${gl_bai}ディスクスペースが不十分です!" - echo "現在利用可能なスペース:$((available_space_mb/1024))g" - echo "最小需要スペース:${required_gb}G" - echo "インストールは継続できません。ディスクスペースを掃除して、もう一度お試しください。" - send_stats "ディスクスペースが不十分です" + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then + echo -e "${gl_huang}ヒント:${gl_bai}ディスク容量が足りません!" + echo "現在利用可能なスペース: $((available_space_mb/1024))G" + echo "最低限必要なスペース:${required_gb}G" + echo "インストールを続行できません。ディスク容量をクリアして、再試行してください。" + send_stats "ディスク容量が足りない" break_end kejilion fi } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { if [ $# -eq 0 ]; then - echo "パッケージパラメーターは提供されていません!" + echo "パッケージパラメータが指定されていません!" return 1 fi for package in "$@"; do - echo -e "${gl_huang}アンインストール$package...${gl_bai}" + echo -e "${gl_huang}アンインストールする$package...${gl_bai}" if command -v dnf &>/dev/null; then dnf remove -y "$package" elif command -v yum &>/dev/null; then @@ -259,14 +269,14 @@ remove() { elif command -v pkg &>/dev/null; then pkg delete -y "$package" else - echo "不明なパッケージマネージャー!" + echo "不明なパッケージマネージャーです!" return 1 fi done } -# さまざまな分布に適したUniversal SystemCTL関数 +# さまざまなディストリビューションに適したユニバーサル systemctl 関数 systemctl() { local COMMAND="$1" local SERVICE_NAME="$2" @@ -279,43 +289,43 @@ systemctl() { } -# サービスを再起動します +# サービスを再起動する restart() { systemctl restart "$1" if [ $? -eq 0 ]; then - echo "$1サービスは再開されました。" + echo "$1サービスが再開されました。" else - echo "エラー:再起動$1サービスは失敗しました。" + echo "エラー: 再起動$1サービスが失敗しました。" fi } -# サービスを開始します +# サービス開始 start() { systemctl start "$1" if [ $? -eq 0 ]; then echo "$1サービスが開始されました。" else - echo "エラー:開始$1サービスは失敗しました。" + echo "エラー: 開始$1サービスが失敗しました。" fi } -# サービスを停止します +# サービスを停止する stop() { systemctl stop "$1" if [ $? -eq 0 ]; then - echo "$1サービスは停止しました。" + echo "$1サービスが停止されました。" else - echo "エラー:停止します$1サービスは失敗しました。" + echo "エラー: 停止$1サービスが失敗しました。" fi } -# サービスのステータスを確認します +# サービスステータスを確認する status() { systemctl status "$1" if [ $? -eq 0 ]; then - echo "$1サービスステータスが表示されます。" + echo "$1サービスのステータスが表示されます。" else - echo "エラー:表示できません$1サービスステータス。" + echo "エラー: 表示できません$1サービスのステータス。" fi } @@ -328,14 +338,14 @@ enable() { /bin/systemctl enable "$SERVICE_NAME" fi - echo "$SERVICE_NAME電源を入れるように設定します。" + echo "$SERVICE_NAME起動時に自動で起動するように設定してあります。" } break_end() { echo -e "${gl_lv}操作が完了しました${gl_bai}" - echo "任意のキーを押して続行します..." + echo "続行するには任意のキーを押してください..." read -n 1 -s -r -p "" echo "" clear @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,80 +417,40 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } install_add_docker() { - echo -e "${gl_huang}Docker環境のインストール...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + echo -e "${gl_huang}Docker 環境をインストールしています...${gl_bai}" + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -504,47 +474,47 @@ while true; do echo "Dockerコンテナリスト" docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" echo "" - echo "コンテナ操作" + echo "コンテナの運用" echo "------------------------" - echo "1.新しいコンテナを作成します" + echo "1. 新しいコンテナを作成する" echo "------------------------" - echo "2。指定されたコンテナを起動します。6。すべての容器を起動します" - echo "3.指定された容器を停止します7。すべての容器を停止します" - echo "4.指定されたコンテナ8を削除します。すべてのコンテナを削除します" - echo "5。指定されたコンテナを再起動9。すべてのコンテナを再起動します" + echo "2. 指定したコンテナを起動します。 6. すべてのコンテナを起動します。" + echo "3. 指定したコンテナを停止します。 7. すべてのコンテナを停止します。" + echo "4. 指定したコンテナを削除します。 8. すべてのコンテナを削除します。" + echo "5. 指定したコンテナを再起動します。 9. すべてのコンテナを再起動します。" echo "------------------------" - echo "11。指定されたコンテナを入力します12。コンテナログを表示します" - echo "13.コンテナネットワークを表示14。コンテナ占有を表示します" + echo "11. 指定したコンテナを入力します。 12. コンテナのログを表示します。" + echo "13. コンテナネットワークを確認します。 14. コンテナ占有率を確認します。" echo "------------------------" - echo "15.コンテナポートアクセスをオンにする16.コンテナポートアクセスをオフにする" + echo "15. コンテナ ポート アクセスを有効にする 16. コンテナ ポート アクセスを閉じる" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "新しいコンテナを作成します" - read -e -p "作成コマンドを入力してください:" dockername + send_stats "新しいコンテナを作成する" + read -e -p "作成コマンドを入力してください:" dockername $dockername ;; 2) - send_stats "指定された容器を起動します" - read -e -p "コンテナ名(スペースで区切られた複数のコンテナ名)を入力してください。" dockername + send_stats "指定したコンテナを起動する" + read -e -p "コンテナ名を入力してください (複数のコンテナ名はスペースで区切ってください):" dockername docker start $dockername ;; 3) - send_stats "指定された容器を停止します" - read -e -p "コンテナ名(スペースで区切られた複数のコンテナ名)を入力してください。" dockername + send_stats "指定したコンテナを停止する" + read -e -p "コンテナ名を入力してください (複数のコンテナ名はスペースで区切ってください):" dockername docker stop $dockername ;; 4) - send_stats "指定されたコンテナを削除します" - read -e -p "コンテナ名(スペースで区切られた複数のコンテナ名)を入力してください。" dockername + send_stats "指定したコンテナを削除します" + read -e -p "コンテナ名を入力してください (複数のコンテナ名はスペースで区切ってください):" dockername docker rm -f $dockername ;; 5) - send_stats "指定された容器を再起動します" - read -e -p "コンテナ名(スペースで区切られた複数のコンテナ名)を入力してください。" dockername + send_stats "指定したコンテナを再起動します" + read -e -p "コンテナ名を入力してください (複数のコンテナ名はスペースで区切ってください):" dockername docker restart $dockername ;; 6) @@ -556,7 +526,7 @@ while true; do docker stop $(docker ps -q) ;; 8) - send_stats "すべてのコンテナを削除します" + send_stats "すべてのコンテナを削除する" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有容器吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -565,7 +535,7 @@ while true; do [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -574,23 +544,23 @@ while true; do docker restart $(docker ps -q) ;; 11) - send_stats "コンテナを入力します" - read -e -p "コンテナ名を入力してください:" dockername - docker exec -it $dockername /bin/sh + send_stats "コンテナに入る" + read -e -p "コンテナ名を入力してください:" dockername + docker exec $dockername /bin/sh break_end ;; 12) - send_stats "コンテナログを表示します" - read -e -p "コンテナ名を入力してください:" dockername + send_stats "コンテナログの表示" + read -e -p "コンテナ名を入力してください:" dockername docker logs $dockername break_end ;; 13) - send_stats "コンテナネットワークを表示します" + send_stats "コンテナネットワークを表示する" echo "" container_ids=$(docker ps -q) echo "------------------------------------------------------------" - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "コンテナ名" "ネットワーク名" "IPアドレス" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") local container_name=$(echo "$container_info" | awk '{print $1}') @@ -604,14 +574,14 @@ while true; do break_end ;; 14) - send_stats "コンテナの占有を表示します" + send_stats "コンテナ占有率の表示" docker stats --no-stream break_end ;; 15) - send_stats "コンテナポートアクセスを許可します" - read -e -p "コンテナ名を入力してください:" docker_name + send_stats "コンテナポートへのアクセスを許可する" + read -e -p "コンテナ名を入力してください:" docker_name ip_address clear_container_rules "$docker_name" "$ipv4_address" local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) @@ -620,8 +590,8 @@ while true; do ;; 16) - send_stats "コンテナポートアクセスをブロックします" - read -e -p "コンテナ名を入力してください:" docker_name + send_stats "コンテナポートへのアクセスをブロックする" + read -e -p "コンテナ名を入力してください:" docker_name ip_address block_container_port "$docker_name" "$ipv4_address" local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) @@ -640,44 +610,44 @@ done docker_image() { while true; do clear - send_stats "Docker画像管理" - echo "Docker画像リスト" + send_stats "Dockerイメージ管理" + echo "Dockerイメージリスト" docker image ls echo "" echo "ミラー操作" echo "------------------------" - echo "1.指定された画像を取得する3。指定された画像を削除します" - echo "2。指定された画像4を更新します。すべての画像を削除します" + echo "1. 指定した画像を取得 3. 指定した画像を削除" + echo "2. 指定した画像を更新 4. すべての画像を削除" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "鏡を引っ張ります" - read -e -p "ミラー名を入力してください(スペースで複数のミラー名を分離してください):" imagenames + send_stats "イメージをプルする" + read -e -p "イメージ名を入力してください (複数のイメージ名はスペースで区切ってください):" imagenames for name in $imagenames; do - echo -e "${gl_huang}画像を取得する:$name${gl_bai}" + echo -e "${gl_huang}画像の取得:$name${gl_bai}" docker pull $name done ;; 2) - send_stats "画像を更新します" - read -e -p "ミラー名を入力してください(スペースで複数のミラー名を分離してください):" imagenames + send_stats "画像を更新" + read -e -p "イメージ名を入力してください (複数のイメージ名はスペースで区切ってください):" imagenames for name in $imagenames; do - echo -e "${gl_huang}更新された画像:$name${gl_bai}" + echo -e "${gl_huang}画像の更新:$name${gl_bai}" docker pull $name done ;; 3) - send_stats "ミラーを削除します" - read -e -p "ミラー名を入力してください(スペースで複数のミラー名を分離してください):" imagenames + send_stats "画像の削除" + read -e -p "イメージ名を入力してください (複数のイメージ名はスペースで区切ってください):" imagenames for name in $imagenames; do docker rmi -f $name done ;; 4) - send_stats "すべての画像を削除します" + send_stats "すべての画像を削除する" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有镜像吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -686,7 +656,7 @@ while true; do [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -754,16 +724,16 @@ install_crontab() { service cron start ;; *) - echo "サポートされていない分布:$ID" + echo "サポートされていないディストリビューション:$ID" return ;; esac else - echo "オペレーティングシステムを決定することはできません。" + echo "オペレーティング システムを特定できません。" return fi - echo -e "${gl_lv}Crontabがインストールされ、Cronサービスが実行されています。${gl_bai}" + echo -e "${gl_lv}crontab がインストールされており、cron サービスが実行されています。${gl_bai}" } @@ -775,27 +745,27 @@ docker_ipv6_on() { local CONFIG_FILE="/etc/docker/daemon.json" local REQUIRED_IPV6_CONFIG='{"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}' - # 構成ファイルが存在するかどうかを確認し、ファイルが存在しない場合はファイルを作成し、デフォルト設定を書き込む + # 構成ファイルが存在するかどうかを確認し、存在しない場合はファイルを作成し、デフォルト設定を書き込みます if [ ! -f "$CONFIG_FILE" ]; then echo "$REQUIRED_IPV6_CONFIG" | jq . > "$CONFIG_FILE" restart docker else - # JQを使用して、構成ファイルの更新を処理します + # jq を使用して構成ファイルの更新を処理する local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # 現在の構成には既にIPv6設定があるかどうかを確認してください + # 現在の構成にすでに ipv6 設定があるかどうかを確認します local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq '.ipv6 // false') - # 構成を更新し、IPv6を有効にします + # 構成を更新してIPv6を有効にする if [[ "$CURRENT_IPV6" == "false" ]]; then UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq '. + {ipv6: true, "fixed-cidr-v6": "2001:db8:1::/64"}') else UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq '. + {"fixed-cidr-v6": "2001:db8:1::/64"}') fi - # 元の構成と新しい構成を比較します + # 元の構成と新しい構成を比較する if [[ "$ORIGINAL_CONFIG" == "$UPDATED_CONFIG" ]]; then - echo -e "${gl_huang}現在、IPv6アクセスが有効になっています${gl_bai}" + echo -e "${gl_huang}IPv6 アクセスは現在有効です${gl_bai}" else echo "$UPDATED_CONFIG" | jq . > "$CONFIG_FILE" restart docker @@ -810,28 +780,28 @@ docker_ipv6_off() { local CONFIG_FILE="/etc/docker/daemon.json" - # 構成ファイルが存在するかどうかを確認します + # 設定ファイルが存在するかどうかを確認する if [ ! -f "$CONFIG_FILE" ]; then - echo -e "${gl_hong}構成ファイルは存在しません${gl_bai}" + echo -e "${gl_hong}設定ファイルが存在しません${gl_bai}" return fi - # 現在の構成をお読みください + # 現在の構成を読み取る local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # JQを使用して、構成ファイルの更新を処理します + # jq を使用して構成ファイルの更新を処理する local UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq 'del(.["fixed-cidr-v6"]) | .ipv6 = false') - # 現在のIPv6ステータスを確認してください + # 現在のIPv6ステータスを確認する local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq -r '.ipv6 // false') - # 元の構成と新しい構成を比較します + # 元の構成と新しい構成を比較する if [[ "$CURRENT_IPV6" == "false" ]]; then - echo -e "${gl_huang}IPv6アクセスは現在閉じられています${gl_bai}" + echo -e "${gl_huang}IPv6アクセスは現在停止中です${gl_bai}" else echo "$UPDATED_CONFIG" | jq . > "$CONFIG_FILE" restart docker - echo -e "${gl_huang}IPv6アクセスは正常に閉じられています${gl_bai}" + echo -e "${gl_huang}IPv6 アクセスが正常に終了しました${gl_bai}" fi } @@ -870,117 +840,117 @@ iptables_open() { open_port() { local ports=($@) # 将传入的参数转换为数组 if [ ${#ports[@]} -eq 0 ]; then - echo "少なくとも1つのポート番号を提供してください" + echo "少なくとも 1 つのポート番号を入力してください" return 1 fi install iptables for port in "${ports[@]}"; do - # 既存のクロージングルールを削除します + # 既存のシャットダウン ルールを削除する iptables -D INPUT -p tcp --dport $port -j DROP 2>/dev/null iptables -D INPUT -p udp --dport $port -j DROP 2>/dev/null - # オープンルールを追加します + # オープンルールを追加 if ! iptables -C INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j ACCEPT fi if ! iptables -C INPUT -p udp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p udp --dport $port -j ACCEPT - echo "ポートが開かれました$port" + echo "ポートがオープンしました$port" fi done save_iptables_rules - send_stats "ポートが開かれました" + send_stats "ポートがオープンしました" } close_port() { local ports=($@) # 将传入的参数转换为数组 if [ ${#ports[@]} -eq 0 ]; then - echo "少なくとも1つのポート番号を提供してください" + echo "少なくとも 1 つのポート番号を入力してください" return 1 fi install iptables for port in "${ports[@]}"; do - # 既存のオープンルールを削除します + # 既存のオープンルールを削除する iptables -D INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null iptables -D INPUT -p udp --dport $port -j ACCEPT 2>/dev/null - # 緊密なルールを追加します + # シャットダウンルールを追加する if ! iptables -C INPUT -p tcp --dport $port -j DROP 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j DROP fi if ! iptables -C INPUT -p udp --dport $port -j DROP 2>/dev/null; then iptables -I INPUT 1 -p udp --dport $port -j DROP - echo "ポートは閉じた$port" + echo "ポートが閉じられています$port" fi done - # 既存のルールを削除する(ある場合) + # 既存のルール (存在する場合) を削除します。 iptables -D INPUT -i lo -j ACCEPT 2>/dev/null iptables -D FORWARD -i lo -j ACCEPT 2>/dev/null - # 最初に新しいルールを挿入します + # 最初のルールに新しいルールを挿入します iptables -I INPUT 1 -i lo -j ACCEPT iptables -I FORWARD 1 -i lo -j ACCEPT save_iptables_rules - send_stats "ポートは閉じた" + send_stats "ポートが閉じられています" } allow_ip() { local ips=($@) # 将传入的参数转换为数组 if [ ${#ips[@]} -eq 0 ]; then - echo "少なくとも1つのIPアドレスまたはIPセグメントを提供してください" + echo "少なくとも 1 つの IP アドレスまたは IP セグメントを入力してください" return 1 fi install iptables for ip in "${ips[@]}"; do - # 既存のブロッキングルールを削除します + # 既存のブロック ルールを削除する iptables -D INPUT -s $ip -j DROP 2>/dev/null - # 許可ルールを追加します + # 許可ルールを追加する if ! iptables -C INPUT -s $ip -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -s $ip -j ACCEPT - echo "IPをリリースしました$ip" + echo "リリース済みIP$ip" fi done save_iptables_rules - send_stats "IPをリリースしました" + send_stats "リリース済みIP" } block_ip() { local ips=($@) # 将传入的参数转换为数组 if [ ${#ips[@]} -eq 0 ]; then - echo "少なくとも1つのIPアドレスまたはIPセグメントを提供してください" + echo "少なくとも 1 つの IP アドレスまたは IP セグメントを入力してください" return 1 fi install iptables for ip in "${ips[@]}"; do - # 既存の許可ルールを削除します + # 既存の許可ルールを削除する iptables -D INPUT -s $ip -j ACCEPT 2>/dev/null - # ブロッキングルールを追加します + # ブロックルールを追加する if ! iptables -C INPUT -s $ip -j DROP 2>/dev/null; then iptables -I INPUT 1 -s $ip -j DROP - echo "IPブロック$ip" + echo "IPがブロックされました$ip" fi done save_iptables_rules - send_stats "IPブロック" + send_stats "IPがブロックされました" } @@ -990,7 +960,7 @@ block_ip() { enable_ddos_defense() { - # 防御DDOをオンにします + # DDoS 保護を有効にする iptables -A DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT iptables -A DOCKER-USER -p tcp --syn -j DROP iptables -A DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT @@ -1000,12 +970,12 @@ enable_ddos_defense() { iptables -A INPUT -p udp -m limit --limit 3000/s -j ACCEPT iptables -A INPUT -p udp -j DROP - send_stats "DDOS防御をオンにします" + send_stats "DDoS 防御をオンにする" } -# DDOS防御をオフにします +# DDoS 防御をオフにする disable_ddos_defense() { - # 防御DDOをオフにします + # DDoS 保護をオフにする iptables -D DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT 2>/dev/null iptables -D DOCKER-USER -p tcp --syn -j DROP 2>/dev/null iptables -D DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null @@ -1015,101 +985,94 @@ disable_ddos_defense() { iptables -D INPUT -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null iptables -D INPUT -p udp -j DROP 2>/dev/null - send_stats "DDOS防御をオフにします" + send_stats "DDoS 防御をオフにする" } -# 国家IPルールを管理する機能 +# 国内の知財ルールを管理する機能 manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # IPSETが存在しない場合は作成します - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # IPエリアファイルをダウンロードします - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "エラー:ダウンロード$country_codeIPゾーンファイルが失敗しました" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # IPSETにIPを追加します - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "エラー: ダウンロード$country_codeIPゾーンファイルが失敗しました" + continue + fi - # iptablesでIPをブロックします - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "正常にブロックされました$country_codeIPアドレス" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # 許可された国のIPSETを作成する(存在しない場合) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "正常にブロックされました$country_codeIPアドレス" + rm "${country_code,,}.zone" + ;; - # IPエリアファイルをダウンロードします - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "エラー:ダウンロード$country_codeIPゾーンファイルが失敗しました" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 既存の国家ルールを削除します - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "エラー: ダウンロード$country_codeIPゾーンファイルが失敗しました" + continue + fi - # IPSETにIPを追加します - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # 指定された国のIPのみが許可されています - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "正常に許可されています$country_codeIPアドレス" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # 国のiptablesルールを削除します - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "正常に許可されました$country_codeIPアドレス" + rm "${country_code,,}.zone" + ;; - # Ipsetを破壊します - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "正常に持ち上げられました$country_codeIPアドレスの制限" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "正常に削除されました$country_codeIPアドレス制限" + ;; + + *) + echo "使用法: manage_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables @@ -1123,35 +1086,35 @@ iptables_panel() { echo "" echo "ファイアウォール管理" echo "------------------------" - echo "1.指定されたポート2を開きます。指定されたポートを閉じます" - echo "3.すべてのポートを開きます。4。すべてのポートを閉じます" + echo "1. 指定されたポートをオープンします。 2. 指定されたポートを閉じます。" + echo "3. すべてのポートを開く 4. すべてのポートを閉じる" echo "------------------------" - echo "5。IPホワイトリスト6。IPブラックリスト" - echo "7.指定されたIPをクリアします" + echo "5. IP ホワイトリスト 6. IP ブラックリスト" + echo "7. 指定したIPをクリアします" echo "------------------------" - echo "11. ping 12を許可します。Pingを無効にします" + echo "11. PING を許可する 12. PING を無効にする" echo "------------------------" - echo "13。DDOS防衛を開始14。DDOS防衛をオフにします" + echo "13. DDOS 防御を開始します。 14. DDOS 防御をオフにします。" echo "------------------------" - echo "15.ブロック指定された国IP16。指定された国のIPのみが許可されます" - echo "17.指定国でのIP制限をリリースします" + echo "15. 指定した国の IP をブロックする 16. 指定した国の IP のみを許可する" + echo "17. 指定国における知的財産制限を解除する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - read -e -p "オープンポート番号を入力してください:" o_port + read -e -p "開いているポート番号を入力してください:" o_port open_port $o_port - send_stats "指定されたポートを開きます" + send_stats "指定したポートを開く" ;; 2) - read -e -p "閉じたポート番号を入力してください:" c_port + read -e -p "閉じられたポート番号を入力してください:" c_port close_port $c_port - send_stats "指定されたポートを閉じます" + send_stats "指定したポートを閉じる" ;; 3) - # すべてのポートを開きます + # すべてのポートを開く current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') iptables -F iptables -X @@ -1164,7 +1127,7 @@ iptables_panel() { iptables -A FORWARD -i lo -j ACCEPT iptables -A INPUT -p tcp --dport $current_port -j ACCEPT iptables-save > /etc/iptables/rules.v4 - send_stats "すべてのポートを開きます" + send_stats "すべてのポートを開く" ;; 4) # すべてのポートを閉じます @@ -1185,35 +1148,35 @@ iptables_panel() { 5) # IPホワイトリスト - read -e -p "リリースするには、IPまたはIPセグメントを入力してください。" o_ip + read -e -p "許可された IP または IP セグメントを入力してください:" o_ip allow_ip $o_ip ;; 6) # IPブラックリスト - read -e -p "ブロックされたIPまたはIPセグメントを入力してください:" c_ip + read -e -p "ブロックされた IP または IP 範囲を入力してください:" c_ip block_ip $c_ip ;; 7) - # 指定されたIPをクリアします - read -e -p "クリアされたIPを入力してください:" d_ip + # 指定したIPをクリア + read -e -p "クリアされた IP を入力してください:" d_ip iptables -D INPUT -s $d_ip -j ACCEPT 2>/dev/null iptables -D INPUT -s $d_ip -j DROP 2>/dev/null iptables-save > /etc/iptables/rules.v4 - send_stats "指定されたIPをクリアします" + send_stats "指定したIPをクリア" ;; 11) - # pingを許可します + # PINGを許可する iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT iptables-save > /etc/iptables/rules.v4 - send_stats "pingを許可します" + send_stats "PINGを許可する" ;; 12) - # pingを無効にします + # PINGを無効にする iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT 2>/dev/null iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT 2>/dev/null iptables-save > /etc/iptables/rules.v4 - send_stats "pingを無効にします" + send_stats "PINGを無効にする" ;; 13) enable_ddos_defense @@ -1223,20 +1186,20 @@ iptables_panel() { ;; 15) - read -e -p "ブロックされた国コード(CN、米国、JPなど)を入力してください。" country_code + read -e -p "ブロックされている国コードを入力してください (CN US JP のように、複数の国コードをスペースで区切ることができます)。" country_code manage_country_rules block $country_code - send_stats "許可された国$country_codeIP" + send_stats "国を許可する$country_codeIP" ;; 16) - read -e -p "許可された国コード(CN、米国、JPなど)を入力してください。" country_code + read -e -p "許可されている国コードを入力してください (CN US JP のように、複数の国コードをスペースで区切ることができます)。" country_code manage_country_rules allow $country_code - send_stats "国をブロックします$country_codeIP" + send_stats "ブロック国$country_codeIP" ;; 17) - read -e -p "クリアされた国コード(CN、米国、JPなど)を入力してください。" country_code + read -e -p "クリアされた国コードを入力してください (CN US JP のように、複数の国コードをスペースで区切ることができます)。" country_code manage_country_rules unblock $country_code - send_stats "国をきれいにします$country_codeIP" + send_stats "澄んだ国$country_codeIP" ;; *) @@ -1252,28 +1215,26 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 - # 現在のシステムですべてのスワップパーティションを取得します + # 現在のシステム内のすべてのスワップ パーティションを取得します local swap_partitions=$(grep -E '^/dev/' /proc/swaps | awk '{print $1}') - # 反復して、すべてのスワップパーティションを削除します + # すべてのスワップ パーティションを走査して削除します for partition in $swap_partitions; do swapoff "$partition" wipefs -a "$partition" mkswap -f "$partition" done - # /swapfileが使用されなくなったことを確認してください + # /swapfile が使用されていないことを確認してください swapoff /swapfile - # 古い /swapfileを削除します + # 古い /swapfile を削除する rm -f /swapfile - # 新しいスワップパーティションを作成します + # 新しいスワップ パーティションを作成する fallocate -l ${new_swap}M /swapfile chmod 600 /swapfile mkswap /swapfile @@ -1288,7 +1249,7 @@ add_swap() { rc-update add local fi - echo -e "仮想メモリサイズは変更されています${gl_huang}${new_swap}${gl_bai}M" + echo -e "仮想メモリのサイズは次のように調整されました。${gl_huang}${new_swap}${gl_bai}M" } @@ -1298,7 +1259,7 @@ check_swap() { local swap_total=$(free -m | awk 'NR==3{print $2}') -# 仮想メモリを作成する必要があるかどうかを判断します +# 仮想メモリを作成する必要があるかどうかを判断する [ "$swap_total" -gt 0 ] || add_swap 1024 @@ -1314,21 +1275,21 @@ local swap_total=$(free -m | awk 'NR==3{print $2}') ldnmp_v() { - # nginxバージョンを取得します + # nginxのバージョンを取得する local nginx_version=$(docker exec nginx nginx -v 2>&1) local nginx_version=$(echo "$nginx_version" | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e "nginx : ${gl_huang}v$nginx_version${gl_bai}" - # MySQLバージョンを取得します + # mysqlのバージョンを取得する local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local mysql_version=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SELECT VERSION();" 2>/dev/null | tail -n 1) echo -n -e " mysql : ${gl_huang}v$mysql_version${gl_bai}" - # PHPバージョンを取得します + # PHPのバージョンを取得する local php_version=$(docker exec php php -v 2>/dev/null | grep -oP "PHP \K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e " php : ${gl_huang}v$php_version${gl_bai}" - # Redisバージョンを取得します + # Redis バージョンを取得する local redis_version=$(docker exec redis redis-server -v 2>&1 | grep -oP "v=+\K[0-9]+\.[0-9]+") echo -e " redis : ${gl_huang}v$redis_version${gl_bai}" @@ -1341,20 +1302,18 @@ ldnmp_v() { install_ldnmp_conf() { - # 必要なディレクトリとファイルを作成します - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + # 必要なディレクトリとファイルを作成する + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl - # docker-compose.ymlファイルをダウンロードして置き換えます + # docker-compose.yml ファイルをダウンロードして置き換えます wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml dbrootpasswd=$(openssl rand -base64 16) ; dbuse=$(openssl rand -hex 4) ; dbusepasswd=$(openssl rand -base64 8) - # docker-compose.ymlファイルに置き換えます + # docker-compose.yml ファイル内で置き換えます sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "stream" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # 国コードを取得します (CN、US など)。 + local country=$(curl -s ipinfo.io/country) + + # 国に基づいてDNSを設定する + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "IPv4優先に切り替えました" +send_stats "IPv4優先に切り替えました" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,11 +1392,19 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # mysqlのチューニング + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear - echo "LDNMP環境がインストールされています" + echo "LDNMP環境がインストールされている" echo "------------------------" ldnmp_v @@ -1420,15 +1425,22 @@ install_certbot() { } + + + + + + + install_ssltls() { - docker stop nginx > /dev/null 2>&1 check_port > /dev/null 2>&1 + docker stop nginx > /dev/null 2>&1 cd ~ local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1450,10 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1454,12 +1469,12 @@ install_ssltls_text() { echo -e "${gl_huang}$yuming公開鍵情報${gl_bai}" cat /etc/letsencrypt/live/$yuming/fullchain.pem echo "" - echo -e "${gl_huang}$yuming秘密のキー情報${gl_bai}" + echo -e "${gl_huang}$yuming秘密鍵情報${gl_bai}" cat /etc/letsencrypt/live/$yuming/privkey.pem echo "" - echo -e "${gl_huang}証明書ストレージパス${gl_bai}" - echo "公開鍵:/etc/letsencrypt/live/$yuming/fullchain.pem" - echo "秘密鍵:/etc/letsencrypt/live/$yuming/privkey.pem" + echo -e "${gl_huang}証明書の保存パス${gl_bai}" + echo "公開キー: /etc/letsencrypt/live/$yuming/fullchain.pem" + echo "秘密鍵: /etc/letsencrypt/live/$yuming/privkey.pem" echo "" } @@ -1468,14 +1483,14 @@ install_ssltls_text() { add_ssl() { -echo -e "${gl_huang}SSL証明書をすばやく申請し、有効期限が切れる前に署名を自動的に更新します${gl_bai}" +echo -e "${gl_huang}SSL 証明書をすばやく申請し、有効期限が切れる前に自動的に更新します${gl_bai}" yuming="${1:-}" if [ -z "$yuming" ]; then add_yuming fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1484,8 +1499,8 @@ ssl_ps ssl_ps() { - echo -e "${gl_huang}適用された証明書の有効期限${gl_bai}" - echo "サイト情報証明書の有効期限" + echo -e "${gl_huang}適用された証明書の有効期限ステータス${gl_bai}" + echo "サイト情報 証明書の有効期限" echo "------------------------" for cert_dir in /etc/letsencrypt/live/*; do local cert_file="$cert_dir/fullchain.pem" @@ -1524,22 +1539,87 @@ certs_status() { local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ -f "$file_path" ]; then - send_stats "ドメイン名証明書の成功したアプリケーション" + send_stats "ドメイン名証明書の申請が成功しました" else - send_stats "ドメイン名証明書のアプリケーションは失敗しました" - echo -e "${gl_hong}知らせ:${gl_bai}証明書申請が失敗しました。次の考えられる理由を確認して、もう一度やり直してください。" - echo -e "1。ドメイン名スペリングエラーdomainドメイン名が正しく入力されているかどうかを確認してください" - echo -e "2。DNS解像度の問題domainドメイン名がこのサーバーIPに対して正しく解決されたことを確認します" - echo -e "3.ネットワーク構成の問題cloudflareワープやその他の仮想ネットワークを使用する場合は、一時的にシャットダウンしてください" - echo -e "4。ファイアウォールの制限orポート80/443が開かれているかどうかを確認して、検証がアクセス可能であることを確認してください" - echo -e "5.アプリケーションの数が制限を超えています➠暗号化を毎週制限(5回/ドメイン名/週)があります" - echo -e "6.国内登録制限domainドメイン名が中国本土で登録されているかどうかを確認してください" - break_end - clear - echo "もう一度展開してみてください$webname" - add_yuming - install_ssltls - certs_status + send_stats "ドメイン名証明書の申請に失敗しました" + echo -e "${gl_hong}知らせ:${gl_bai}証明書の申請に失敗しました。次の考えられる理由を確認して、再試行してください。" + echo -e "1. ドメイン名のスペルが間違っています ➠ ドメイン名が正しく入力されているかどうかを確認してください" + echo -e "2. DNS 解決の問題 ➠ ドメイン名がサーバー IP に正しく解決されていることを確認します。" + echo -e "3. ネットワーク構成の問題 ➠ Cloudflare Warp などの仮想ネットワークを使用している場合は、一時的にシャットダウンしてください" + echo -e "4. ファイアウォールの制限 ➠ ポート 80/443 が開いているかどうかを確認し、アクセス可能であることを確認します。" + echo -e "5. アプリケーション数が制限を超えている ➠ Let's Encrypt には週制限あり (5 回/ドメイン名/週)" + echo -e "6. 国内登録制限 ➠ 中国本土環境の場合は、ドメイン名が登録されているかをご確認ください。" + echo "------------------------" + echo "1. 再度適用します。 2. 既存の証明書をインポートします。 3. 証明書なしで HTTP アクセスを使用します。 0. 終了します。" + echo "------------------------" + read -e -p "選択肢を入力してください:" sub_choice + case $sub_choice in + 1) + send_stats "再申請" + echo "もう一度デプロイしてみてください$webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "既存の証明書をインポートする" + + # ファイルパスを定義する + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. 証明書を入力します (ECC 証明書と RSA 証明書はどちらも BEGIN CERTIFICATE で始まります) + echo "証明書 (CRT/PEM) の内容を貼り付けてください (Enter を 2 回押して終了します)。" + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. 秘密キーを入力します (RSA、ECC、PKCS#8 と互換性があります) + echo "証明書の秘密キー (Private Key) の内容を貼り付けてください (Enter を 2 回押して終了します)。" + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. インテリジェントな検証 + # 「BEGIN CERTIFICATE」と「PRIVATE KEY」を含めるだけで渡されます + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # 現在の証明書の種類を特定して表示します。 + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "ECC証明書が正常に保存されたことが検出されました。" + else + echo "RSA証明書が正常に保存されたことが検出されました。" + fi + auth_method="ssl_imported" + else + echo "エラー: 証明書または秘密キーの形式が無効です。" + certs_status + fi + + ;; + 3) + send_stats "証明書なしの HTTP アクセスに切り替える" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "申請を取り下げる" + exit + ;; + esac fi } @@ -1556,11 +1636,45 @@ fi add_yuming() { ip_address - echo -e "最初にドメイン名をローカルIPに解決します。${gl_huang}$ipv4_address $ipv6_address${gl_bai}" - read -e -p "IPまたは解決されたドメイン名を入力してください:" yuming + echo -e "まず、ドメイン名をローカル IP に解決します。${gl_huang}$ipv4_address $ipv6_address${gl_bai}" + read -e -p "IP または解決されたドメイン名を入力してください:" yuming +} + + +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "デフォルトで 80 を使用するには、アクセス/リスニング ポートを入力し、Enter キーを押してください。" access_port + access_port=${access_port:-80} + fi } + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # access_port が空の場合はスキップします + [ -z "$access_port" ] && return 0 + + # すべてのリッスン行を削除します + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # サーバー { の後に新しいリッスンを挿入します + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1685,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1694,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1621,8 +1716,8 @@ nginx_upgrade() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi docker restart $ldnmp_pods > /dev/null 2>&1 - send_stats "更新します$ldnmp_pods" - echo "更新します${ldnmp_pods}仕上げる" + send_stats "更新する$ldnmp_pods" + echo "更新する${ldnmp_pods}仕上げる" } @@ -1635,14 +1730,14 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address check_docker_app_ip - echo "ログイン情報:" - echo "ユーザー名:$dbuse" + echo "ログイン情報:" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" echo send_stats "起動する$ldnmp_pods" @@ -1655,29 +1750,29 @@ cf_purge_cache() { local EMAIL local ZONE_IDS - # 構成ファイルが存在するかどうかを確認します + # 設定ファイルが存在するかどうかを確認する if [ -f "$CONFIG_FILE" ]; then - # 構成ファイルからAPI_TOKENとZONE_IDを読み取ります + # 構成ファイルから API_TOKEN とzone_idを読み取ります read API_TOKEN EMAIL ZONE_IDS < "$CONFIG_FILE" - # ゾーン_idsを配列に変換します + # ZONE_IDS を配列に変換する ZONE_IDS=($ZONE_IDS) else - # キャッシュをクリーニングするかどうかをユーザーに促します - read -e -p "CloudFlareのキャッシュをきれいにする必要がありますか? (y/n):" answer + # キャッシュをクリアするかどうかをユーザーに確認する + read -e -p "Cloudflareのキャッシュをクリアする必要がありますか? (y/n):" answer if [[ "$answer" == "y" ]]; then - echo "CF情報が保存されます$CONFIG_FILE、後でCF情報を変更できます" - read -e -p "API_TOKENを入力してください:" API_TOKEN - read -e -p "CFユーザー名を入力してください:" EMAIL - read -e -p "ゾーン_id(スペースで区切られた複数)を入力してください。" -a ZONE_IDS + echo "CF情報は以下に保存されます。$CONFIG_FILECF 情報は後で変更できます。" + read -e -p "API_TOKEN を入力してください:" API_TOKEN + read -e -p "CF ユーザー名を入力してください:" EMAIL + read -e -p "zone_id を入力してください (複数の場合はスペースで区切ります):" -a ZONE_IDS mkdir -p /home/web/config/ echo "$API_TOKEN $EMAIL ${ZONE_IDS[*]}" > "$CONFIG_FILE" fi fi - # 各ZONE_IDをループして、Clear Cacheコマンドを実行します + # 各zone_idをループし、キャッシュクリアコマンドを実行します。 for ZONE_ID in "${ZONE_IDS[@]}"; do - echo "ゾーン_idのキャッシュのクリア:$ZONE_ID" + echo "zone_id のキャッシュをクリアします:$ZONE_ID" curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \ -H "X-Auth-Email: $EMAIL" \ -H "X-Auth-Key: $API_TOKEN" \ @@ -1691,38 +1786,37 @@ cf_purge_cache() { web_cache() { - send_stats "サイトキャッシュをクリーンアップします" + send_stats "サイトキャッシュをクリアする" cf_purge_cache cd /home/web && docker compose restart - restart_redis } web_del() { - send_stats "サイトデータを削除します" + send_stats "サイトデータを削除する" yuming_list="${1:-}" if [ -z "$yuming_list" ]; then - read -e -p "サイトデータを削除するには、ドメイン名を入力してください(複数のドメイン名がスペースで区切られています):" yuming_list + read -e -p "サイト データを削除するには、ドメイン名を入力してください (複数のドメイン名はスペースで区切ります)。" yuming_list if [[ -z "$yuming_list" ]]; then return fi fi for yuming in $yuming_list; do - echo "ドメイン名の削除:$yuming" + echo "ドメイン名が削除されています:$yuming" rm -r /home/web/html/$yuming > /dev/null 2>&1 rm /home/web/conf.d/$yuming.conf > /dev/null 2>&1 rm /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 rm /home/web/certs/${yuming}_cert.pem > /dev/null 2>&1 - # ドメイン名をデータベース名に変換します + # ドメイン名をデータベース名に変換する dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') - # エラーを避けるために、データベースを削除する前にデータベースが存在するかどうかを確認します - echo "データベースの削除:$dbname" + # エラーを避けるために、データベースを削除する前にデータベースが存在するかどうかを確認してください。 + echo "データベースを削除しています:$dbname" docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE ${dbname};" > /dev/null 2>&1 done @@ -1738,23 +1832,23 @@ nginx_waf() { wget -O /home/web/nginx.conf "${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf" fi - # モードパラメーターに従ってWAFをオンまたはオフにすることにしました + # モードパラメータに従ってWAFをオンにするかオフにするかを決定します。 if [ "$mode" == "on" ]; then - # WAFをオンにしてください:コメントを削除します + # WAF をオンにする: コメントを削除する sed -i 's|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity on;|\1modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 elif [ "$mode" == "off" ]; then - # WAFを閉じる:コメントを追加します + # WAF をオフにする: コメントを追加する sed -i 's|^load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity on;|\1# modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "無効なパラメーター:「オン」または「オフ」を使用します" + echo "無効な引数: 'on' または 'off' を使用してください" return 1 fi - # nginx画像を確認し、状況に応じてそれらを処理します + # nginx イメージを確認し、それに応じて処理します if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1768,7 +1862,7 @@ check_waf_status() { if grep -q "^\s*#\s*modsecurity on;" /home/web/nginx.conf; then waf_status="" elif grep -q "modsecurity on;" /home/web/nginx.conf; then - waf_status=" WAF已开启" + waf_status="WAFがオンになっている" else waf_status="" fi @@ -1776,8 +1870,8 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then - CFmessage=" cf模式已开启" + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then + CFmessage="cfモードがオンになっています" else CFmessage="" fi @@ -1801,11 +1895,11 @@ patch_wp_memory_limit() { local TARGET_DIR="/home/web/html" # 路径写死 find "$TARGET_DIR" -type f -name "wp-config.php" | while read -r FILE; do - # 古い定義を削除します + # 古い定義を削除する sed -i "/define(['\"]WP_MEMORY_LIMIT['\"].*/d" "$FILE" sed -i "/define(['\"]WP_MAX_MEMORY_LIMIT['\"].*/d" "$FILE" - # 「Happy Publishing」で行の前に新しい定義を挿入する + # 「Happy Publishing」を含む行の前に新しい定義を挿入します。 awk -v insert="define('WP_MEMORY_LIMIT', '$MEMORY_LIMIT');\ndefine('WP_MAX_MEMORY_LIMIT', '$MAX_MEMORY_LIMIT');" \ ' /Happy publishing/ { @@ -1828,12 +1922,12 @@ patch_wp_debug() { local TARGET_DIR="/home/web/html" # 路径写死 find "$TARGET_DIR" -type f -name "wp-config.php" | while read -r FILE; do - # 古い定義を削除します + # 古い定義を削除する sed -i "/define(['\"]WP_DEBUG['\"].*/d" "$FILE" sed -i "/define(['\"]WP_DEBUG_DISPLAY['\"].*/d" "$FILE" sed -i "/define(['\"]WP_DEBUG_LOG['\"].*/d" "$FILE" - # 「Happy Publishing」で行の前に新しい定義を挿入する + # 「Happy Publishing」を含む行の前に新しい定義を挿入します。 awk -v insert="define('WP_DEBUG_DISPLAY', $DEBUG_DISPLAY);\ndefine('WP_DEBUG_LOG', $DEBUG_LOG);" \ ' /Happy publishing/ { @@ -1847,6 +1941,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # 古い定義を削除する + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # 挿入コンテンツの生成 + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # 「出版おめでとうございます」の前に挿入 + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1856,7 +1987,7 @@ nginx_br() { fi if [ "$mode" == "on" ]; then - # Brotliをオンにする:コメントを削除します + # Brotli をオンにする: コメントを削除する sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1870,7 +2001,7 @@ nginx_br() { sed -i '/brotli_types/,+6 s/^\(\s*\)#\s*/\1/' /home/web/nginx.conf elif [ "$mode" == "off" ]; then - # Brotliを閉じる:コメントを追加します + # Brotliを閉じる: コメントを追加 sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1886,11 +2017,11 @@ nginx_br() { }' /home/web/nginx.conf else - echo "無効なパラメーター:「オン」または「オフ」を使用します" + echo "無効な引数: 'on' または 'off' を使用してください" return 1 fi - # nginx画像を確認し、状況に応じてそれらを処理します + # nginx イメージを確認し、それに応じて処理します if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1912,7 +2043,7 @@ nginx_zstd() { fi if [ "$mode" == "on" ]; then - # ZSTDをオンにしてください:コメントを削除します + # Zstd をオンにする: コメントを削除する sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1927,7 +2058,7 @@ nginx_zstd() { elif [ "$mode" == "off" ]; then - # ZSTDを閉じる:コメントを追加します + # Zstdを閉じる: コメントを追加 sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1943,11 +2074,11 @@ nginx_zstd() { else - echo "無効なパラメーター:「オン」または「オフ」を使用します" + echo "無効な引数: 'on' または 'off' を使用してください" return 1 fi - # nginx画像を確認し、状況に応じてそれらを処理します + # nginx イメージを確認し、それに応じて処理します if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1974,7 +2105,7 @@ nginx_gzip() { elif [ "$mode" == "off" ]; then sed -i 's|^\(\s*\)gzip on;|\1# gzip on;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "無効なパラメーター:「オン」または「オフ」を使用します" + echo "無効な引数: 'on' または 'off' を使用してください" return 1 fi @@ -1990,45 +2121,42 @@ nginx_gzip() { web_security() { send_stats "LDNMP環境防御" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "サーバーWebサイト防衛プログラム${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "サーバー Web サイト防御プログラム${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" - echo "1.防衛プログラムをインストールします" + echo "1. 防御プログラムをインストールする" echo "------------------------" - echo "5。SSHインターセプトレコードを表示6。ウェブサイト傍受記録を見る" - echo "7。防衛ルールのリストを表示8。ログのリアルタイム監視を表示" + echo "5. SSH 傍受記録の表示 6. Web サイト傍受記録の表示" + echo "7. 防御ルールのリストを表示します。 8. リアルタイム監視のログを表示します。" echo "------------------------" - echo "11.インターセプトパラメーターを構成12。すべてのブロックされたipsをクリアします" + echo "11. インターセプトパラメータを設定します。 12. ブロックされたすべての IP をクリアします。" echo "------------------------" - echo "21。CloudFlareモード22。5秒シールドの高負荷" + echo "21. クラウドフレア モード 22. 高負荷時に 5 秒間のシールドを有効にする" echo "------------------------" - echo "31。WAF32をオンにしてください。WAFをオフにします" - echo "33。DDOS防衛をオンにする34。DDOS防衛をオフにする" + echo "31. WAF をオンにする 32. WAF をオフにする" + echo "33. DDOS 防御をオンにする 34. DDOS 防御をオフにする" echo "------------------------" - echo "9.防衛プログラムをアンインストールします" + echo "9. 防御プログラムをアンインストールする" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,93 +2170,94 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null - echo "Fail2Ban防衛プログラムがアンインストールされています" + echo "Fail2Ban 防御プログラムがアンインストールされました" + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) - send_stats "CloudFlareモード" - echo "CF背景の右上隅に移動し、左側のAPIトークンを選択し、グローバルAPIキーを取得します" + send_stats "クラウドフレアモード" + echo "cf バックエンドの右上隅にある私のプロフィールに移動し、左側で API トークンを選択し、グローバル API キーを取得します。" echo "https://dash.cloudflare.com/login" - read -e -p "CFアカウント番号を入力します:" cfuser - read -e -p "CFのグローバルAPIキーを入力してください:" cftoken + read -e -p "CF の口座番号を入力してください:" cfuser + read -e -p "CF のグローバル API キーを入力します。" cftoken wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status - echo "CloudFlareモードは、CFバックグラウンド、サイトセキュリティイベントでインターセプトレコードを表示するように構成されています" + echo "Cloudflare モードが設定されており、傍受記録は cf バックグラウンド、site-security-events で表示できます。" ;; 22) - send_stats "5秒シールドでの高負荷" - echo -e "${gl_huang}ウェブサイトは5分ごとに自動的に検出されます。高負荷が検出されると、シールドが自動的にオンになり、低負荷が5秒間自動的にオフになります。${gl_bai}" + send_stats "高負荷により5秒シールドが可能" + echo -e "${gl_huang}Web サイトは 5 分ごとに自動的に検出します。高負荷を検出すると自動的にシールドが開き、低負荷を検出すると5秒間自動的にシールドが閉じます。${gl_bai}" echo "--------------" - echo "CFパラメーターを取得します:" - echo -e "CFバックグラウンドの右上隅に移動し、左側のAPIトークンを選択して、取得します${gl_huang}Global API Key${gl_bai}" - echo -e "CFバックグラウンドドメイン名の概要ページの右下に移動して${gl_huang}リージョンID${gl_bai}" + echo "CFパラメータを取得します。" + echo -e "cf バックエンドの右上隅にある私のプロフィールに移動し、左側で API トークンを選択して、${gl_huang}Global API Key${gl_bai}" + echo -e "cf バックエンド ドメイン名の概要ページの右下に移動して取得します。${gl_huang}エリアID${gl_bai}" echo "https://dash.cloudflare.com/login" echo "--------------" - read -e -p "CFアカウント番号を入力します:" cfuser - read -e -p "CFのグローバルAPIキーを入力してください:" cftoken - read -e -p "CFにドメイン名の領域IDを入力します。" cfzonID + read -e -p "CF の口座番号を入力してください:" cfuser + read -e -p "CF のグローバル API キーを入力します。" cftoken + read -e -p "CF にドメイン名のゾーン ID を入力します。" cfzonID cd ~ install jq bc @@ -2145,9 +2274,9 @@ web_security() { if [ -z "$existing_cron" ]; then (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "高負荷自動シールドオープニングスクリプトが追加されました" + echo "高負荷自動シールド開放スクリプトを追加しました" else - echo "自動シールドスクリプトはすでに存在しています、それを追加する必要はありません" + echo "自動シールド開放スクリプトはすでに存在するため、追加する必要はありません" fi ;; @@ -2160,8 +2289,8 @@ web_security() { 32) nginx_waf off - echo "サイトWAFは閉鎖されています" - send_stats "サイトWAFは閉鎖されています" + echo "サイト WAF がダウンしています" + send_stats "サイト WAF がダウンしています" ;; 33) @@ -2176,26 +2305,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { - -CONFIG_FILE="/home/web/nginx.conf" +check_ldnmp_mode() { -# 現在のworker_processesの設定値を取得します -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# 値に応じてモード情報を設定します -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # MySQL 設定ファイルに 4096M が含まれているかどうかを確認する + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info="ハイパフォーマンスモード" + else + mode_info="標準モード" + fi @@ -2204,25 +2330,25 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" - # ZSTDが有効になっていてコメントされていないかどうかを確認します(ZSTDで行全体が開始されます;) + # zstd がオンでコメントが解除されているかどうかを確認します (行全体が zstd on で始まります)。 if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then - zstd_status=" zstd压缩已开启" + zstd_status="zstd圧縮がオンになっています" else zstd_status="" fi - # Brotliが有効であり、コメントされていないかどうかを確認してください + # Brotli が有効になっていてコメントが解除されているかどうかを確認します if grep -qE '^\s*brotli\s+on;' "$CONFIG_FILE"; then - br_status=" br压缩已开启" + br_status="br圧縮がオンになっています" else br_status="" fi - # GZIPが有効になっており、コメントされていないかどうかを確認してください + # gzip が有効になっていてコメントが解除されているかどうかを確認します if grep -qE '^\s*gzip\s+on;' "$CONFIG_FILE"; then - gzip_status=" gzip压缩已开启" + gzip_status="gzip圧縮がオンになっています" else gzip_status="" fi @@ -2233,36 +2359,38 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear - send_stats "LDNMP環境を最適化します" - echo -e "LDNMP環境を最適化します${gl_lv}${mode_info}${gzip_status}${br_status}${zstd_status}${gl_bai}" + send_stats "LDNMP環境の最適化" + echo -e "LDNMP環境の最適化${gl_lv}${mode_info}${gzip_status}${br_status}${zstd_status}${gl_bai}" echo "------------------------" - echo "1。標準モード2。高性能モード(推奨2H4g以上)" + echo "1.スタンダードモード 2.ハイパフォーマンスモード(2H4G以上推奨)" echo "------------------------" - echo "3。GZIP圧縮をオンにします4。GZIP圧縮をオフにします" - echo "5。BR圧縮をオンにします6。BR圧縮をオフにします" - echo "7。ZSTD圧縮をオンにします8。ZSTD圧縮をオフにします" + echo "3. gzip 圧縮をオンにする 4. gzip 圧縮をオフにする" + echo "5. br 圧縮をオンにする 6. br 圧縮をオフにする" + echo "7. zstd 圧縮をオンにする 8. zstd 圧縮をオフにする" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) send_stats "サイト標準モード" - # nginxチューニング - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf - # PHPチューニング + + # PHPのチューニング wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini docker cp /home/optimized_php.ini php:/usr/local/etc/php/conf.d/optimized_php.ini docker cp /home/optimized_php.ini php74:/usr/local/etc/php/conf.d/optimized_php.ini rm -rf /home/optimized_php.ini - # PHPチューニング + # PHPのチューニング wget -O /home/www.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/www-1.conf docker cp /home/www.conf php:/usr/local/etc/php-fpm.d/www.conf docker cp /home/www.conf php74:/usr/local/etc/php-fpm.d/www.conf @@ -2274,7 +2402,7 @@ web_optimization() { fix_phpfpm_conf php fix_phpfpm_conf php74 - # mysqlチューニング + # mysqlのチューニング wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ rm -rf /home/custom_mysql_config.cnf @@ -2282,7 +2410,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced @@ -2290,19 +2417,21 @@ web_optimization() { ;; 2) - send_stats "サイトの高性能モード" + send_stats "サイトハイパフォーマンスモード" - # nginxチューニング - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + # nginxのチューニング + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf - # PHPチューニング + # PHPのチューニング wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini docker cp /home/optimized_php.ini php:/usr/local/etc/php/conf.d/optimized_php.ini docker cp /home/optimized_php.ini php74:/usr/local/etc/php/conf.d/optimized_php.ini rm -rf /home/optimized_php.ini - # PHPチューニング + # PHPのチューニング wget -O /home/www.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/www.conf docker cp /home/www.conf php:/usr/local/etc/php-fpm.d/www.conf docker cp /home/www.conf php74:/usr/local/etc/php-fpm.d/www.conf @@ -2314,17 +2443,16 @@ web_optimization() { fix_phpfpm_conf php fix_phpfpm_conf php74 - # mysqlチューニング + # mysqlのチューニング wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config.cnf docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ rm -rf /home/custom_mysql_config.cnf cd /home/web && docker compose restart - restart_redis optimize_web_server - echo "LDNMP環境は、高性能モードに設定されています" + echo "LDNMP 環境が高パフォーマンス モードに設定されている" ;; 3) @@ -2371,23 +2499,30 @@ web_optimization() { +check_docker_app() { + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then + check_docker="${gl_lv}インストール済み${gl_bai}" + else + check_docker="${gl_hui}インストールされていません${gl_bai}" + fi +} -check_docker_app() { +# check_docker_app() { -if docker inspect "$docker_name" &>/dev/null; then - check_docker="${gl_lv}已安装${gl_bai}" -else - check_docker="${gl_hui}未安装${gl_bai}" -fi +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then +# check_docker="${gl_lv} は ${gl_bai} をインストールしました" +# else +# check_docker="${gl_hui} がインストールされていません ${gl_bai}" +# fi -} +# } check_docker_app_ip() { echo "------------------------" -echo "アクセスアドレス:" +echo "訪問先住所:" ip_address @@ -2416,59 +2551,66 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. 地域検査 + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # コンテナの作成時間と画像名を取得します + # 2. ローカルミラー情報の取得 local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) + [[ -z "$container_info" ]] && return - # ミラーウェアハウスとタグを抽出します - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} - - # デフォルトのラベルは最新です - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" - - # 公式画像のサポートを追加します - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. インテリジェントな配線判断 + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- シナリオ A: GitHub (ghcr.io) 上のミラー --- + # ウェアハウスのパスを抽出します (例: ghcr.io/onexru/oneimg -> onexru/oneimg) + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # 注: ghcr.io の API は比較的複雑です。通常、最も早い方法は、GitHub リポジトリのリリースを確認することです + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- シナリオB:特別指定(Docker HubでもGitHub Releaseで判断したい) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # Docker Hub APIから画像公開時間を取得します - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- シナリオ C: 標準 Docker ハブ --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # 買収の時間を確認します - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # タイムスタンプを比較します - if [[ $container_created_ts -lt $last_updated_ts ]]; then - update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" + # 4. タイムスタンプの比較 + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then + update_status="${gl_huang}新しいバージョンが見つかりました!${gl_bai}" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 - # コンテナのIPアドレスを取得します + # コンテナのIPアドレスを取得する local container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name_or_id") if [ -z "$container_ip" ]; then @@ -2478,34 +2620,34 @@ block_container_port() { install iptables - # 他のすべてのIPSを確認してブロックします + # 他のすべての IP をチェックしてブロックします if ! iptables -C DOCKER-USER -p tcp -d "$container_ip" -j DROP &>/dev/null; then iptables -I DOCKER-USER -p tcp -d "$container_ip" -j DROP fi - # 指定されたIPを確認してリリースします + # 指定したIPの確認と解放 if ! iptables -C DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # ローカルネットワークを確認してリリースします127.0.0.0/8 + # ローカルネットワーク127.0.0.0/8を確認して許可します。 if ! iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi - # 他のすべてのIPSを確認してブロックします + # 他のすべての IP をチェックしてブロックします if ! iptables -C DOCKER-USER -p udp -d "$container_ip" -j DROP &>/dev/null; then iptables -I DOCKER-USER -p udp -d "$container_ip" -j DROP fi - # 指定されたIPを確認してリリースします + # 指定したIPの確認と解放 if ! iptables -C DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # ローカルネットワークを確認してリリースします127.0.0.0/8 + # ローカルネットワーク127.0.0.0/8を確認して許可します。 if ! iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2515,7 +2657,7 @@ block_container_port() { fi - echo "IP+ポートは、サービスへのアクセスをブロックされています" + echo "IP+ポートはサービスへのアクセスをブロックされています" save_iptables_rules } @@ -2526,7 +2668,7 @@ clear_container_rules() { local container_name_or_id=$1 local allowed_ip=$2 - # コンテナのIPアドレスを取得します + # コンテナのIPアドレスを取得する local container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name_or_id") if [ -z "$container_ip" ]; then @@ -2536,17 +2678,17 @@ clear_container_rules() { install iptables - # 他のすべてのIPをブロックするルールを明確にします + # 他のすべての IP をブロックする明確なルール if iptables -C DOCKER-USER -p tcp -d "$container_ip" -j DROP &>/dev/null; then iptables -D DOCKER-USER -p tcp -d "$container_ip" -j DROP fi - # 指定されたIPをリリースするためのルールをクリアします + # 指定したIPを許可するルールをクリアします if iptables -C DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # ローカルネットワークをリリースするためのルールをクリア127.0.0.0/8 + # ローカルネットワーク 127.0.0.0/8 を許可するルールをクリアします if iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2555,17 +2697,17 @@ clear_container_rules() { - # 他のすべてのIPをブロックするルールを明確にします + # 他のすべての IP をブロックする明確なルール if iptables -C DOCKER-USER -p udp -d "$container_ip" -j DROP &>/dev/null; then iptables -D DOCKER-USER -p udp -d "$container_ip" -j DROP fi - # 指定されたIPをリリースするためのルールをクリアします + # 指定したIPを許可するルールをクリアします if iptables -C DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # ローカルネットワークをリリースするためのルールをクリア127.0.0.0/8 + # ローカルネットワーク 127.0.0.0/8 を許可するルールをクリアします if iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2576,7 +2718,7 @@ clear_container_rules() { fi - echo "IP+ポートはサービスにアクセスすることが許可されています" + echo "IP+ポートによるサービスへのアクセスが許可されました" save_iptables_rules } @@ -2590,25 +2732,25 @@ block_host_port() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "エラー:アクセスを許可されているポート番号とIPを提供してください。" - echo "使用法:block_host_port <ポート番号> <承認IP>" + echo "エラー: アクセスを許可するには、ポート番号と IP を入力してください。" + echo "使用法: block_host_port <ポート番号> <許可された IP>" return 1 fi install iptables - # 他のすべてのIPアクセスを拒否しました + # 他のすべての IP からのアクセスを拒否する if ! iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -j DROP fi - # 指定されたIPアクセスを許可します + # 指定したIPへのアクセスを許可する if ! iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # ローカルアクセスを許可します + # ローカルアクセスを許可する if ! iptables -C INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi @@ -2617,27 +2759,27 @@ block_host_port() { - # 他のすべてのIPアクセスを拒否しました + # 他のすべての IP からのアクセスを拒否する if ! iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -j DROP fi - # 指定されたIPアクセスを許可します + # 指定したIPへのアクセスを許可する if ! iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # ローカルアクセスを許可します + # ローカルアクセスを許可する if ! iptables -C INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 確立された関連接続および関連する接続のトラフィックを許可します + # 確立された接続と関連する接続のトラフィックを許可する if ! iptables -C INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT &>/dev/null; then iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT fi - echo "IP+ポートは、サービスへのアクセスをブロックされています" + echo "IP+ポートはサービスへのアクセスをブロックされています" save_iptables_rules } @@ -2649,47 +2791,47 @@ clear_host_port_rules() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "エラー:アクセスを許可されているポート番号とIPを提供してください。" - echo "使用法:CLEAR_HOST_PORT_RULES <ポート番号> <認定IP>" + echo "エラー: アクセスを許可するには、ポート番号と IP を入力してください。" + echo "使用法: clear_host_port_rules <ポート番号> <許可された IP>" return 1 fi install iptables - # 他のすべてのIPアクセスをブロックするルールをクリアします + # 他のすべての IP からのアクセスをブロックするルールをクリアします if iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -j DROP fi - # ネイティブアクセスを可能にするルールを明確にします + # ローカルアクセスを許可する明確なルール if iptables -C INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 指定されたIPアクセスを許可するルールを明確にします + # 指定したIPからのアクセスを許可する明確なルール if iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # 他のすべてのIPアクセスをブロックするルールをクリアします + # 他のすべての IP からのアクセスをブロックするルールをクリアします if iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -j DROP fi - # ネイティブアクセスを可能にするルールを明確にします + # ローカルアクセスを許可する明確なルール if iptables -C INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 指定されたIPアクセスを許可するルールを明確にします + # 指定したIPからのアクセスを許可する明確なルール if iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - echo "IP+ポートはサービスにアクセスすることが許可されています" + echo "IP+ポートによるサービスへのアクセスが許可されました" save_iptables_rules } @@ -2698,16 +2840,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2720,7 +2879,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2731,29 +2890,31 @@ while true; do fi echo "" echo "------------------------" - echo "1。インストール2。更新3。アンインストール" + echo "1. インストール 2. アップデート 3. アンインストール" echo "------------------------" - echo "5.ドメイン名アクセスを追加6。ドメイン名アクセスを削除する" - echo "7. IP+ポートアクセスを許可8。BlockIP+ポートアクセス" + echo "5. ドメイン名アクセスを追加します。 6. ドメイン名アクセスを削除します。" + echo "7. IP+ポートアクセスを許可します。 8. IP+ポートアクセスをブロックします。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) - check_disk_space $app_size - read -e -p "アプリケーション外部サービスポートを入力し、デフォルトを入力します${docker_port}ポート:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "アプリケーションの外部サービス ポートを入力し、Enter キーを押して、それをデフォルトで使用します。${docker_port}ポート:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + add_app_id + clear - echo "$docker_nameインストール" + echo "$docker_nameインストール完了" check_docker_app_ip echo "" $docker_use @@ -2764,43 +2925,48 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum + + add_app_id + clear - echo "$docker_nameインストール" + echo "$docker_nameインストール完了" check_docker_app_ip echo "" $docker_use $docker_passwd - send_stats "更新します$docker_name" + send_stats "更新する$docker_name" ;; 3) docker rm -f "$docker_name" docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf - echo "アプリはアンインストールされています" - send_stats "アンインストール$docker_name" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "アプリがアンインストールされました" + send_stats "アンインストールする$docker_name" ;; 5) - echo "${docker_name}ドメインアクセス設定" - send_stats "${docker_name}ドメインアクセス設定" + echo "${docker_name}ドメイン名アクセス設定" + send_stats "${docker_name}ドメイン名アクセス設定" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" ;; 6) - echo "ドメイン名フォーマットexample.comにはhttps://が付属していません" + echo "ドメイン名の形式 example.com (https:// なし)" web_del ;; 7) - send_stats "IPアクセスを許可します${docker_name}" + send_stats "IPアクセスを許可する${docker_name}" clear_container_rules "$docker_name" "$ipv4_address" ;; 8) - send_stats "IPアクセスをブロックします${docker_name}" + send_stats "IPアクセスをブロックする${docker_name}" block_container_port "$docker_name" "$ipv4_address" ;; @@ -2817,7 +2983,6 @@ done - docker_app_plus() { send_stats "$app_name" while true; do @@ -2827,7 +2992,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2838,50 +3003,62 @@ docker_app_plus() { fi echo "" echo "------------------------" - echo "1。インストール2。更新3。アンインストール" + echo "1. インストール 2. アップデート 3. アンインストール" echo "------------------------" - echo "5.ドメイン名アクセスを追加6。ドメイン名アクセスを削除する" - echo "7. IP+ポートアクセスを許可8。BlockIP+ポートアクセス" + echo "5. ドメイン名アクセスを追加します。 6. ドメイン名アクセスを削除します。" + echo "7. IP+ポートアクセスを許可します。 8. IP+ポートアクセスをブロックします。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) - check_disk_space $app_size - read -e -p "アプリケーション外部サービスポートを入力し、デフォルトを入力します${docker_port}ポート:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "アプリケーションの外部サービス ポートを入力し、Enter キーを押して、それをデフォルトで使用します。${docker_port}ポート:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + + add_app_id + send_stats "$app_nameインストール" ;; + 2) docker_app_update + add_app_id + send_stats "$app_name更新する" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_nameアンインストールする" ;; + 5) - echo "${docker_name}ドメインアクセス設定" - send_stats "${docker_name}ドメインアクセス設定" + echo "${docker_name}ドメイン名アクセス設定" + send_stats "${docker_name}ドメイン名アクセス設定" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) - echo "ドメイン名フォーマットexample.comにはhttps://が付属していません" + echo "ドメイン名の形式 example.com (https:// なし)" web_del ;; 7) - send_stats "IPアクセスを許可します${docker_name}" + send_stats "IPアクセスを許可する${docker_name}" clear_container_rules "$docker_name" "$ipv4_address" ;; 8) - send_stats "IPアクセスをブロックします${docker_name}" + send_stats "IPアクセスをブロックする${docker_name}" block_container_port "$docker_name" "$ipv4_address" ;; *) @@ -2920,7 +3097,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2929,7 +3106,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2939,7 +3116,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -2966,7 +3143,7 @@ tmux_run_d() { local base_name="tmuxd" local tmuxd_ID=1 -# セッションが存在するかどうかを確認する関数 +# セッションが存在するかどうかを確認する機能 session_exists() { tmux has-session -t $1 2>/dev/null } @@ -2976,7 +3153,7 @@ while session_exists "$base_name-$tmuxd_ID"; do local tmuxd_ID=$((tmuxd_ID + 1)) done -# 新しいTMUXセッションを作成します +# 新しい tmux セッションを作成する tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" @@ -2985,52 +3162,41 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx +} + +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}インストール済み${gl_bai}" + else + check_f2b_status="${gl_hui}インストールされていません${gl_bai}" + fi } f2b_install_sshd() { - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf - else + fi + + if command -v apt &>/dev/null; then install rsyslog systemctl start rsyslog systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog fi - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } f2b_sshd() { @@ -3051,7 +3217,7 @@ server_reboot() { read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}现在重启服务器吗?(Y/N): ")" rboot case "$rboot" in [Yy]) - echo "再起動" + echo "再起動しました" reboot ;; *) @@ -3098,8 +3264,8 @@ ldnmp_install_status_one() { if docker inspect "php" &>/dev/null; then clear - send_stats "LDNMP環境を再度インストールできません" - echo -e "${gl_huang}ヒント:${gl_bai}ウェブサイトの建設環境がインストールされています。再度インストールする必要はありません!" + send_stats "LDNMP環境を再インストールできません" + echo -e "${gl_huang}ヒント:${gl_bai}ウェブサイト構築環境を導入しました。再度インストールする必要はありません。" break_end linux_ldnmp fi @@ -3109,12 +3275,11 @@ ldnmp_install_status_one() { ldnmp_install_all() { cd ~ -send_stats "LDNMP環境をインストールします" +send_stats "LDNMP環境をインストールする" root_use clear -echo -e "${gl_huang}LDNMP環境はインストールされていません。LDNMP環境のインストールを開始します...${gl_bai}" -check_disk_space 3 -check_port +echo -e "${gl_huang}LDNMP環境がインストールされていません。 LDNMP 環境のインストールを開始します...${gl_bai}" +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3126,12 +3291,11 @@ install_ldnmp nginx_install_all() { cd ~ -send_stats "Nginx環境をインストールします" +send_stats "nginx環境をインストールする" root_use clear -echo -e "${gl_huang}nginxはインストールされていません、nginx環境のインストールを開始します...${gl_bai}" -check_disk_space 1 -check_port +echo -e "${gl_huang}nginx がインストールされていません。nginx 環境のインストールを開始してください...${gl_bai}" +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3140,8 +3304,8 @@ nginx_upgrade clear local nginx_version=$(docker exec nginx nginx -v 2>&1) local nginx_version=$(echo "$nginx_version" | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+") -echo "Nginxがインストールされています" -echo -e "現在のバージョン:${gl_huang}v$nginx_version${gl_bai}" +echo "nginxがインストールされました" +echo -e "現在のバージョン:${gl_huang}v$nginx_version${gl_bai}" echo "" } @@ -3152,7 +3316,7 @@ echo "" ldnmp_install_status() { if ! docker inspect "php" &>/dev/null; then - send_stats "LDNMP環境を最初にインストールしてください" + send_stats "最初に LDNMP 環境をインストールしてください" ldnmp_install_all fi @@ -3162,7 +3326,7 @@ ldnmp_install_status() { nginx_install_status() { if ! docker inspect "nginx" &>/dev/null; then - send_stats "最初にNGINX環境をインストールしてください" + send_stats "まずnginx環境をインストールしてください" nginx_install_all fi @@ -3173,7 +3337,7 @@ nginx_install_status() { ldnmp_web_on() { clear - echo "あなたの$webname建てられた!" + echo "あなたの$webname建てられました!" echo "https://$yuming" echo "------------------------" echo "$webnameインストール情報は次のとおりです。" @@ -3181,10 +3345,21 @@ ldnmp_web_on() { } nginx_web_on() { - clear - echo "あなたの$webname建てられた!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + echo "あなたの$webname建てられました!" + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3195,73 +3370,93 @@ ldnmp_wp() { webname="WordPress" yuming="${1:-}" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" if [ -z "$yuming" ]; then add_yuming fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# エコー「データベース名:$ dbname」 -# エコー「ユーザー名:$ dbuse」 -# エコー「パスワード:$ dbusepasswd」 -# エコー「データベースアドレス:mysql」 -# エコー「テーブルプレフィックス:WP_」 } + ldnmp_Proxy() { clear - webname="反向代理-IP+端口" + webname="リバースプロキシ IP+ポート" yuming="${1:-}" reverseproxy="${2:-}" port="${3:-}" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "抗ジェネレーションIPを入力してください:" reverseproxy + read -e -p "アンチジェネレーション IP を入力してください (Enter キーを押すとデフォルトでローカル IP 127.0.0.1 になります):" reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then - read -e -p "発生防止ポートを入力してください。" port + read -e -p "アンチジェネレーションポートを入力してください:" port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 動的に追加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3271,41 +3466,43 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear - webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" + webname="リバースプロキシ負荷分散" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" if [ -z "$yuming" ]; then add_yuming fi - # ユーザーが入力した複数のIPを取得:ポート(スペースで区切られています) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then - read -e -p "スペースで区切られた複数の生成防止IP+ポートを入力してください(たとえば、127.0.0.1:3000 127.0.1:3002):" reverseproxy_port + read -e -p "複数のアンチジェネレーション IP + ポートをスペースで区切って入力してください (例: 127.0.0.1:3000 127.0.0.1:3002):" reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # 上流の構成を動的に生成します upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # テンプレートのプレースホルダーを交換します - sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i "s/# 動的に追加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" nginx_http_on docker exec nginx nginx -s reload @@ -3314,6 +3511,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "サービス名" "通信タイプ" "ローカルアドレス" "バックエンドアドレス" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # サービス名はファイル名を取得します + service_name=$(basename "$conf" .conf) + + # 上流ブロックでサーバーのバックエンド IP:ポートを取得します。 + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # リッスンポートの取得 + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # デフォルトのローカルIP + ip_address + local_ip="$ipv4_address" + + # ファイル名の接尾辞または内容から最初に判断して通信タイプを取得します + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # スプライス リスニング IP:ポート + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "ストリーム 4 層プロキシ" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "ストリーム 4 層プロキシ転送ツール$check_docker $update_status" + echo "NGINX Stream は NGINX の TCP/UDP プロキシ モジュールであり、高性能のトランスポート層トラフィック転送とロード バランシングを実現するために使用されます。" + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. インストール 2. アップデート 3. アンインストール" + echo "------------------------" + echo "4. 転送サービスの追加 5. 転送サービスの変更 6. 転送サービスの削除" + echo "------------------------" + echo "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択内容を入力してください:" choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "Stream 4 層エージェントのインストール" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "ストリームの 4 層プロキシを更新します" + ;; + 3) + read -e -p "nginx コンテナを削除してもよろしいですか?これはウェブサイトの機能に影響を与える可能性があります。 (y/N):" confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "ストリームの 4 層プロキシを更新します" + echo "nginxコンテナは削除されました。" + else + echo "操作はキャンセルされました。" + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "レイヤー 4 プロキシを追加する" + ;; + 5) + send_stats "転送設定の編集" + read -e -p "編集するサービス名を入力してください:" stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "レイヤ 4 プロキシを変更する" + ;; + 6) + send_stats "転送設定の削除" + read -e -p "削除するサービス名を入力してください:" stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "レイヤ 4 プロキシを削除する" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="ストリーム 4 層プロキシ負荷分散" + + send_stats "インストール$webname" + echo "導入を開始する$webname" + + # エージェント名を取得する + read -rp "プロキシ転送名を入力してください (例: mysql_proxy):" proxy_name + if [ -z "$proxy_name" ]; then + echo "名前を空にすることはできません"; return 1 + fi + + # リスニングポートの取得 + read -rp "ローカルのリスニング ポート (3306 など) を入力してください。" listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "ポートは数値である必要があります"; return 1 + fi + + echo "契約の種類を選択してください:" + echo "1. TCP 2. UDP" + read -rp "シリアル番号を入力してください [1-2]:" proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "無効な選択"; return 1 ;; + esac + + read -e -p "1 つ以上のバックエンド IP + ポートをスペースで区切って入力してください (例: 10.13.0.2:3306 10.13.0.3:3306)。" reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 動的に追加/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "あなたの$webname建てられました!" + echo "------------------------" + echo "訪問先住所:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3331,20 +3722,19 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear - send_stats "LDNMPサイト管理" + send_stats "LDNMP サイト管理" echo "LDNMP環境" echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output}証明書の有効期限" + echo -e "サイト:${output}証明書の有効期限" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3355,9 +3745,28 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "データベース:${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" @@ -3369,48 +3778,44 @@ ldnmp_web_status() { echo -e "データ${gl_hui}/home/web/html${gl_bai}証明書${gl_hui}/home/web/certs${gl_bai}構成${gl_hui}/home/web/conf.d${gl_bai}" echo "------------------------" echo "" - echo "動作します" + echo "操作する" echo "------------------------" - echo "1.ドメイン名証明書を適用/更新する2。サイトドメイン名を変更します" - echo "3.サイトキャッシュをクリーンアップ4。関連するサイトを作成する" - echo "5.アクセスログを表示6。エラーログを表示します" - echo "7.グローバル構成の編集8。サイト構成の編集" - echo "9.サイトデータベースの管理10。サイト分析レポートを表示します" + echo "1. ドメイン名証明書の適用/更新 2. サイトのドメイン名の複製" + echo "3. サイトのキャッシュをクリアします。 4. 関連するサイトを作成します。" + echo "5. アクセスログの表示 6. エラーログの表示" + echo "7. グローバル構成の編集 8. サイト構成の編集" + echo "9. サイトデータベースの管理 10. サイト分析レポートの表示" echo "------------------------" - echo "20.指定されたサイトデータを削除します" + echo "20. 指定したサイトデータを削除する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "ドメイン名証明書を申請します" - read -e -p "ドメイン名を入力してください:" yuming + send_stats "ドメイン名証明書を申請する" + read -e -p "ドメイン名を入力してください:" yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "サイトドメイン名を変更します" - echo -e "${gl_hong}強くお勧めします:${gl_bai}最初にサイトデータ全体をバックアップしてから、サイトドメイン名を変更します!" - read -e -p "古いドメイン名を入力してください:" oddyuming - read -e -p "新しいドメイン名を入力してください:" yuming + send_stats "クローンサイトのドメイン名" + read -e -p "古いドメイン名を入力してください:" oddyuming + read -e -p "新しいドメイン名を入力してください:" yuming install_certbot install_ssltls certs_status - # MySQLの交換 - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3420,19 +3825,16 @@ ldnmp_web_status() { done done - # ウェブサイトディレクトリの交換 - mv /home/web/html/$oddyuming /home/web/html/$yuming + # Web サイトのディレクトリの置き換え + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3441,10 +3843,10 @@ ldnmp_web_status() { web_cache ;; 4) - send_stats "関連するサイトを作成します" - echo -e "アクセスのための既存のサイトの新しいドメイン名を関連付ける" - read -e -p "既存のドメイン名を入力してください:" oddyuming - read -e -p "新しいドメイン名を入力してください:" yuming + send_stats "関連サイトの作成" + echo -e "新しいドメイン名を既存のサイトに関連付けてアクセスする" + read -e -p "既存のドメイン名を入力してください:" oddyuming + read -e -p "新しいドメイン名を入力してください:" yuming install_certbot install_ssltls certs_status @@ -3458,25 +3860,25 @@ ldnmp_web_status() { ;; 5) - send_stats "アクセスログを表示します" + send_stats "アクセスログを見る" tail -n 200 /home/web/log/nginx/access.log break_end ;; 6) - send_stats "エラーログを表示します" + send_stats "エラーログを表示する" tail -n 200 /home/web/log/nginx/error.log break_end ;; 7) - send_stats "グローバル構成を編集します" + send_stats "グローバル構成の編集" install nano nano /home/web/nginx.conf docker exec nginx nginx -s reload ;; 8) - send_stats "サイト構成を編集します" - read -e -p "サイト構成を編集するには、編集するドメイン名を入力してください。" yuming + send_stats "サイト構成を編集する" + read -e -p "サイト構成を編集するには、編集するドメイン名を入力してください:" yuming install nano nano /home/web/conf.d/$yuming.conf docker exec nginx nginx -s reload @@ -3486,14 +3888,14 @@ ldnmp_web_status() { break_end ;; 10) - send_stats "サイトデータを表示します" + send_stats "サイトデータの表示" install goaccess goaccess --log-format=COMBINED /home/web/log/nginx/access.log ;; 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3508,7 +3910,7 @@ ldnmp_web_status() { check_panel_app() { if $lujing > /dev/null 2>&1; then - check_panel="${gl_lv}已安装${gl_bai}" + check_panel="${gl_lv}インストール済み${gl_bai}" else check_panel="" fi @@ -3522,32 +3924,38 @@ while true; do clear check_panel_app echo -e "$panelname $check_panel" - echo "${panelname}最近では人気のある強力な運用および保守管理パネルです。" - echo "公式ウェブサイトの紹介:$panelurl " + echo "${panelname}人気の強力な運用保守管理盤です。" + echo "公式サイト紹介:$panelurl " echo "" echo "------------------------" - echo "1。インストール2。管理3。アンインストール" + echo "1. インストール 2. 管理 3. アンインストール" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) check_disk_space 1 install wget iptables_open panel_app_install + + add_app_id send_stats "${panelname}インストール" ;; 2) panel_app_manage + + add_app_id send_stats "${panelname}コントロール" ;; 3) panel_app_uninstall - send_stats "${panelname}アンインストール" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "${panelname}アンインストールする" ;; *) break @@ -3563,9 +3971,9 @@ done check_frp_app() { if [ -d "/home/frp/" ]; then - check_frp="${gl_lv}已安装${gl_bai}" + check_frp="${gl_lv}インストール済み${gl_bai}" else - check_frp="${gl_hui}未安装${gl_bai}" + check_frp="${gl_hui}インストールされていません${gl_bai}" fi } @@ -3591,8 +3999,8 @@ donlond_frp() { generate_frps_config() { - send_stats "FRPサーバーをインストールします" - # ランダムポートと資格情報を生成します + send_stats "FRPサーバーをインストールする" + # ランダムなポートと認証情報を生成する local bind_port=8055 local dashboard_port=8056 local token=$(openssl rand -hex 16) @@ -3613,17 +4021,17 @@ EOF donlond_frp frps - # 出力生成情報 + # 生成された情報を出力する ip_address echo "------------------------" - echo "クライアントの展開に必要なパラメーター" - echo "サービスIP:$ipv4_address" + echo "クライアントの展開に必要なパラメータ" + echo "サービスIP:$ipv4_address" echo "token: $token" echo echo "FRPパネル情報" - echo "FRPパネルアドレス:http://$ipv4_address:$dashboard_port" - echo "FRPパネルのユーザー名:$dashboard_user" - echo "FRPパネルパスワード:$dashboard_pwd" + echo "FRPパネルアドレス:http://$ipv4_address:$dashboard_port" + echo "FRP パネルのユーザー名:$dashboard_user" + echo "FRPパネルのパスワード:$dashboard_pwd" echo open_port 8055 8056 @@ -3633,9 +4041,9 @@ EOF configure_frpc() { - send_stats "FRPクライアントをインストールします" - read -e -p "外部ネットワークドッキングIPを入力してください:" server_addr - read -e -p "外部ネットワークドッキングトークンを入力してください:" token + send_stats "FRPクライアントをインストールする" + read -e -p "外部ネットワークのドッキング IP を入力してください:" server_addr + read -e -p "外部ネットワーク ドッキング トークンを入力してください:" token echo mkdir -p /home/frp @@ -3655,17 +4063,17 @@ EOF } add_forwarding_service() { - send_stats "FRPイントラネットサービスを追加します" - # ユーザーにサービス名と転送情報を入力するように促します - read -e -p "サービス名を入力してください:" service_name - read -e -p "転送タイプ(TCP/UDP)を入力してください[デフォルトTCPを入力]:" service_type + send_stats "FRPイントラネットサービスを追加" + # ユーザーにサービス名と転送情報の入力を求めるプロンプトを表示します + read -e -p "サービス名を入力してください:" service_name + read -e -p "転送タイプ (tcp/udp) を入力してください [デフォルトで tcp を入力する]:" service_type local service_type=${service_type:-tcp} - read -e -p "イントラネットIPを入力してください[デフォルト127.0.0.1を入力]:" local_ip + read -e -p "イントラネット IP を入力してください [Enter キーを押すときのデフォルトは 127.0.0.1]:" local_ip local local_ip=${local_ip:-127.0.0.1} - read -e -p "イントラネットポートを入力してください:" local_port - read -e -p "外部ネットワークポートを入力してください:" remote_port + read -e -p "イントラネット ポートを入力してください:" local_port + read -e -p "外部ネットワーク ポートを入力してください:" remote_port - # ユーザー入力を構成ファイルに書き込みます + # ユーザー入力を構成ファイルに書き込む cat <> /home/frp/frpc.toml [$service_name] type = ${service_type} @@ -3675,8 +4083,8 @@ remote_port = ${remote_port} EOF - # 出力生成情報 - echo "仕える$service_nameFRPC.TOMLに正常に追加されました" + # 生成された情報を出力する + echo "仕える$service_namefrpc.toml に正常に追加されました" docker restart frpc @@ -3687,12 +4095,12 @@ EOF delete_forwarding_service() { - send_stats "FRPイントラネットサービスを削除します" - # ユーザーに削除する必要があるサービス名を入力するように促します - read -e -p "削除する必要があるサービス名を入力してください:" service_name - # SEDを使用して、サービスとその関連構成を削除します + send_stats "FRPイントラネットサービスの削除" + # 削除する必要があるサービスの名前を入力するようにユーザーに求めます + read -e -p "削除するサービス名を入力してください:" service_name + # sed を使用してサービスとその関連構成を削除します sed -i "/\[$service_name\]/,/^$/d" /home/frp/frpc.toml - echo "仕える$service_nameFRPC.TOMLから削除されました" + echo "仕える$service_namefrpc.toml から正常に削除されました" docker restart frpc @@ -3703,7 +4111,7 @@ list_forwarding_services() { local config_file="$1" # ヘッダーを印刷します - printf "%-20s %-25s %-30s %-10s\n" "服务名称" "内网地址" "外网地址" "协议" + printf "%-20s %-25s %-30s %-10s\n" "サービス名" "イントラネットアドレス" "外部ネットワークアドレス" "プロトコル" awk ' BEGIN { @@ -3723,7 +4131,7 @@ list_forwarding_services() { } /^\[.*\]/ { - # サービス情報がある場合は、新しいサービスを処理する前に現在のサービスを印刷します + # サービス情報がすでに存在する場合は、新しいサービスを処理する前に現在のサービスを出力します。 if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3736,7 +4144,7 @@ list_forwarding_services() { if ($1 != "[common]") { gsub(/[\[\]]/, "", $1) current_service=$1 - # 前の値をクリアします + # 前回の値をクリア local_ip="" local_port="" remote_port="" @@ -3765,7 +4173,7 @@ list_forwarding_services() { } END { - # 最後のサービスの情報を印刷します + # 最後のサービスに関する情報を出力します if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3778,17 +4186,17 @@ list_forwarding_services() { -# FRPサーバーポートを取得します +# FRPサーバーポートの取得 get_frp_ports() { mapfile -t ports < <(ss -tulnape | grep frps | awk '{print $5}' | awk -F':' '{print $NF}' | sort -u) } -# アクセスアドレスを生成します +# アクセスアドレスの生成 generate_access_urls() { - # 最初にすべてのポートを取得します + # まずすべてのポートを取得します get_frp_ports - # 8055/8056以外のポートがあるかどうかを確認してください + # 8055/8056以外のポートがあるか確認する local has_valid_ports=false for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3801,14 +4209,14 @@ generate_access_urls() { if [ "$has_valid_ports" = true ]; then echo "FRPサービス外部アクセスアドレス:" - # IPv4アドレスを処理します + # IPv4 アドレスの処理 for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then echo "http://${ipv4_address}:${port}" fi done - # IPv6アドレスを処理する(存在する場合) + # IPv6 アドレスが存在する場合は処理します if [ -n "$ipv6_address" ]; then for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3817,7 +4225,7 @@ generate_access_urls() { done fi - # HTTPS構成の処理 + # HTTPS 構成を処理する for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then local frps_search_pattern="${ipv4_address}:${port}" @@ -3845,6 +4253,7 @@ frps_main_ports() { frps_panel() { send_stats "FRPサーバー" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3852,30 +4261,32 @@ frps_panel() { check_frp_app check_docker_image_update $docker_name echo -e "FRPサーバー$check_frp $update_status" - echo "FRPイントラネット侵入サービス環境を構築して、パブリックIPなしでインターネットにデバイスを公開する" - echo "公式ウェブサイトの紹介:https://github.com/fatedier/frp/" - echo "ビデオ教育:https://www.bilibili.com/video/bv1ymw6e2ewl?t=124.0" + echo "FRPイントラネットペネトレーションサービス環境を構築し、パブリックIPを持たないデバイスをインターネットに公開" + echo "公式サイト紹介:https://github.com/fatedier/frp/" + echo "ビデオチュートリアル: https://www.bilibili.com/video/BV1yMw6e2EwL?t=124.0" if [ -d "/home/frp/" ]; then check_docker_app_ip frps_main_ports fi echo "" echo "------------------------" - echo "1。インストール2。更新3。アンインストール" + echo "1. インストール 2. アップデート 3. アンインストール" echo "------------------------" - echo "5。イントラネットサービスのドメイン名アクセス6。ドメイン名アクセスを削除する" + echo "5. イントラネット サービスのドメイン名アクセス 6. ドメイン名アクセスの削除" echo "------------------------" - echo "7. IP+ポートアクセスを許可8。BlockIP+ポートアクセス" + echo "7. IP+ポートアクセスを許可します。 8. IP+ポートアクセスをブロックします。" echo "------------------------" - echo "00。サービスのステータスを更新します0。前のメニューに戻ります" + echo "00. サービスステータスを更新します。 0. 前のメニューに戻ります。" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) install jq grep ss install_docker generate_frps_config - echo "FRPサーバーがインストールされています" + + add_app_id + echo "FRPサーバーを導入しました" ;; 2) crontab -l | grep -v 'frps' | crontab - > /dev/null 2>&1 @@ -3883,7 +4294,9 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps - echo "FRPサーバーが更新されました" + + add_app_id + echo "FRPサーバーを更新しました" ;; 3) crontab -l | grep -v 'frps' | crontab - > /dev/null 2>&1 @@ -3893,37 +4306,38 @@ frps_panel() { close_port 8055 8056 - echo "アプリはアンインストールされています" + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "アプリがアンインストールされました" ;; 5) - echo "ドメイン名アクセスへの逆イントラネット侵入サービス" - send_stats "FRP外部ドメイン名へのアクセス" + echo "ドメイン名アクセスへのイントラネット侵入サービスのリバース" + send_stats "FRP 外部ドメイン名アクセス" add_yuming - read -e -p "イントラネット侵入サービスポートを入力してください:" frps_port + read -e -p "イントラネット侵入サービス ポートを入力してください:" frps_port ldnmp_Proxy ${yuming} 127.0.0.1 ${frps_port} block_host_port "$frps_port" "$ipv4_address" ;; 6) - echo "ドメイン名フォーマットexample.comにはhttps://が付属していません" + echo "ドメイン名の形式 example.com (https:// なし)" web_del ;; 7) - send_stats "IPアクセスを許可します" - read -e -p "リリースするポートを入力してください:" frps_port + send_stats "IPアクセスを許可する" + read -e -p "解放する必要があるポートを入力してください:" frps_port clear_host_port_rules "$frps_port" "$ipv4_address" ;; 8) - send_stats "IPアクセスをブロックします" - echo "アンチジェネレーションドメイン名にアクセスした場合、この関数を使用して、より安全なIP+ポートアクセスをブロックできます。" - read -e -p "ブロックする必要があるポートを入力してください。" frps_port + send_stats "IPアクセスをブロックする" + echo "ドメイン名アクセスを逆にしている場合は、この機能を使用して IP+ポート アクセスをブロックすることができ、より安全になります。" + read -e -p "ブロックするポートを入力してください:" frps_port block_host_port "$frps_port" "$ipv4_address" ;; 00) - send_stats "FRPサービスステータスを更新します" - echo "FRPサービスステータスは更新されました" + send_stats "FRPサービスステータスを更新" + echo "FRPサービスステータスが更新されました" ;; *) @@ -3937,6 +4351,7 @@ frps_panel() { frpc_panel() { send_stats "FRPクライアント" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do @@ -3944,9 +4359,9 @@ frpc_panel() { check_frp_app check_docker_image_update $docker_name echo -e "FRPクライアント$check_frp $update_status" - echo "サーバーでドッキングした後、ドッキングした後、インターネットへのアクセスにイントラネット侵入サービスを作成できます" - echo "公式ウェブサイトの紹介:https://github.com/fatedier/frp/" - echo "ビデオ教育:https://www.bilibili.com/video/bv1ymw6e2ewl?t=173.9" + echo "サーバーに接続します。接続後、インターネットにアクセスするためのイントラネット侵入サービスを作成できます。" + echo "公式サイト紹介:https://github.com/fatedier/frp/" + echo "ビデオチュートリアル: https://www.bilibili.com/video/BV1yMw6e2EwL?t=173.9" echo "------------------------" if [ -d "/home/frp/" ]; then [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml @@ -3954,18 +4369,20 @@ frpc_panel() { fi echo "" echo "------------------------" - echo "1。インストール2。更新3。アンインストール" + echo "1. インストール 2. アップデート 3. アンインストール" echo "------------------------" - echo "4.外部サービスの追加5.外部サービスを削除6。サービスを手動で構成する" + echo "4. 外部サービスの追加 5. 外部サービスの削除 6. サービスの手動構成" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) install jq grep ss install_docker configure_frpc + + add_app_id echo "FRPクライアントがインストールされています" ;; 2) @@ -3974,6 +4391,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc + + add_app_id echo "FRPクライアントが更新されました" ;; @@ -3983,7 +4402,9 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 - echo "アプリはアンインストールされています" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "アプリがアンインストールされました" ;; 4) @@ -4013,6 +4434,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4022,68 +4444,74 @@ yt_menu_pro() { while true; do if [ -x "/usr/local/bin/yt-dlp" ]; then - local YTDLP_STATUS="${gl_lv}已安装${gl_bai}" + local YTDLP_STATUS="${gl_lv}インストール済み${gl_bai}" else - local YTDLP_STATUS="${gl_hui}未安装${gl_bai}" + local YTDLP_STATUS="${gl_hui}インストールされていません${gl_bai}" fi clear - send_stats "YT-DLPダウンロードツール" + send_stats "yt-dlp ダウンロードツール" echo -e "yt-dlp $YTDLP_STATUS" - echo -e "YT-DLPは、YouTube、Bilibili、Twitterなどを含む何千ものサイトをサポートする強力なビデオダウンロードツールです。" - echo -e "公式ウェブサイトの住所:https://github.com/yt-dlp/yt-dlp" + echo -e "yt-dlp は、YouTube、Bilibili、Twitter などの何千ものサイトをサポートする強力な動画ダウンロード ツールです。" + echo -e "公式サイトアドレス:https://github.com/yt-dlp/yt-dlp" echo "-------------------------" - echo "ダウンロードされたビデオリスト:" - ls -td "$VIDEO_DIR"/*/ 2>/dev/null || echo "(まだありません)" + echo "ダウンロードしたビデオのリスト:" + ls -td "$VIDEO_DIR"/*/ 2>/dev/null || echo "(まだありません)" echo "-------------------------" - echo "1。インストール2。更新3。アンインストール" + echo "1. インストール 2. アップデート 3. アンインストール" echo "-------------------------" - echo "5。シングルビデオダウンロード6。バッチビデオダウンロード7。カスタムパラメーターダウンロード" - echo "8。mp3オーディオ9としてダウンロードします。ビデオディレクトリ10を削除します。クッキー管理(開発中)" + echo "5. 単一ビデオのダウンロード 6. バッチビデオのダウンロード 7. カスタムパラメータのダウンロード" + echo "8. MP3 オーディオとしてダウンロード 9. ビデオ ディレクトリを削除 10. Cookie 管理 (開発中)" echo "-------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "-------------------------" - read -e -p "オプション番号を入力してください:" choice + read -e -p "オプション番号を入力してください:" choice case $choice in 1) - send_stats "YT-DLPのインストール..." - echo "YT-DLPのインストール..." + send_stats "yt-dlp をインストールしています..." + echo "yt-dlp をインストールしています..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp - echo "インストールが完了しました。任意のキーを押して続行します..." + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id + echo "インストールが完了しました。続行するには任意のキーを押してください..." read ;; 2) - send_stats "yt-dlpを更新..." - echo "yt-dlpを更新..." - sudo yt-dlp -U - echo "更新が完了しました。任意のキーを押して続行します..." + send_stats "yt-dlp を更新しています..." + echo "yt-dlp を更新しています..." + yt-dlp -U + + add_app_id + echo "アップデートが完了しました。続行するには任意のキーを押してください..." read ;; 3) - send_stats "yt-dlpのアンインストール..." - echo "yt-dlpのアンインストール..." - sudo rm -f /usr/local/bin/yt-dlp - echo "アンインストールが完了しました。任意のキーを押して続行します..." + send_stats "yt-dlp をアンインストールしています..." + echo "yt-dlp をアンインストールしています..." + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "アンインストールが完了しました。続行するには任意のキーを押してください..." read ;; 5) - send_stats "単一のビデオダウンロード" - read -e -p "ビデオリンクを入力してください:" url + send_stats "単一のビデオのダウンロード" + read -e -p "ビデオリンクを入力してください:" url yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "ダウンロードが完了したら、任意のキーを押して続行します..." ;; + read -e -p "ダウンロードが完了しました。続行するには任意のキーを押してください..." ;; 6) - send_stats "バッチビデオのダウンロード" + send_stats "ビデオのバッチダウンロード" install nano if [ ! -f "$URL_FILE" ]; then - echo -e "#複数のビデオリンクアドレスを入力\ n#https://www.bilibili.com/bangumi/play/ep733316?spm_id_from=333.337.0.0&from_spmid=666.25.Episode.0" > "$URL_FILE" + echo -e "# 複数のビデオ リンク アドレスを入力します\n# https://www.bilibili.com/bangumi/play/ep733316?spm_id_from=333.337.0.0&from_spmid=666.25.episode.0" > "$URL_FILE" fi nano $URL_FILE - echo "バッチダウンロードを開始します..." + echo "今すぐバッチダウンロードを開始してください..." yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ @@ -4091,31 +4519,31 @@ yt_menu_pro() { -a "$URL_FILE" \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "バッチのダウンロードが完了し、任意のキーを押して続行します..." ;; + read -e -p "バッチダウンロードが完了しました。続行するには任意のキーを押してください..." ;; 7) send_stats "カスタムビデオのダウンロード" - read -e -p "完全なYT-DLPパラメーター(YT-DLPを除く)を入力してください。" custom + read -e -p "完全な yt-dlp パラメータを入力してください (yt-dlp を除く)。" custom yt-dlp -P "$VIDEO_DIR" $custom \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "実行が完了したら、キーを押して続行します..." ;; + read -e -p "実行が完了しました。続行するには任意のキーを押してください..." ;; 8) send_stats "MP3ダウンロード" - read -e -p "ビデオリンクを入力してください:" url + read -e -p "ビデオリンクを入力してください:" url yt-dlp -P "$VIDEO_DIR" -x --audio-format mp3 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "オーディオのダウンロードが完了しました、任意のキーを押して続行します..." ;; + read -e -p "音声のダウンロードが完了しました。続行するには任意のキーを押してください..." ;; 9) - send_stats "ビデオを削除します" - read -e -p "削除ビデオの名前を入力してください:" rmdir + send_stats "ビデオを削除する" + read -e -p "削除されたビデオの名前を入力してください:" rmdir rm -rf "$VIDEO_DIR/$rmdir" ;; *) @@ -4151,7 +4579,7 @@ set_timedate() { -# DPKG割り込みの問題を修正します +# dpkgの中断問題を修正 fix_dpkg() { pkill -9 -f 'apt|dpkg' rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock @@ -4160,7 +4588,7 @@ fix_dpkg() { linux_update() { - echo -e "${gl_huang}システムの更新...${gl_bai}" + echo -e "${gl_huang}システムアップデート中です...${gl_bai}" if command -v dnf &>/dev/null; then dnf -y update elif command -v yum &>/dev/null; then @@ -4179,7 +4607,7 @@ linux_update() { elif command -v opkg &>/dev/null; then opkg update else - echo "不明なパッケージマネージャー!" + echo "不明なパッケージマネージャーです!" return fi } @@ -4187,7 +4615,7 @@ linux_update() { linux_clean() { - echo -e "${gl_huang}システムのクリーンアップ...${gl_bai}" + echo -e "${gl_huang}システムクリーニング中...${gl_bai}" if command -v dnf &>/dev/null; then rpm --rebuilddb dnf autoremove -y @@ -4216,11 +4644,11 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v apk &>/dev/null; then - echo "パッケージマネージャーのキャッシュを掃除します..." + echo "パッケージマネージャーのキャッシュをクリーンアップ..." apk cache clean - echo "システムログを削除してください..." + echo "システムログを削除します..." rm -rf /var/log/* - echo "APKキャッシュを削除してください..." + echo "APKキャッシュを削除..." rm -rf /var/cache/apk/* echo "一時ファイルを削除します..." rm -rf /tmp/* @@ -4240,23 +4668,23 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v opkg &>/dev/null; then - echo "システムログを削除してください..." + echo "システムログを削除します..." rm -rf /var/log/* echo "一時ファイルを削除します..." rm -rf /tmp/* elif command -v pkg &>/dev/null; then - echo "未使用の依存関係をクリーンアップ..." + echo "未使用の依存関係をクリーンアップします..." pkg autoremove -y - echo "パッケージマネージャーのキャッシュを掃除します..." + echo "パッケージマネージャーのキャッシュをクリーンアップ..." pkg clean -y - echo "システムログを削除してください..." + echo "システムログを削除します..." rm -rf /var/log/* echo "一時ファイルを削除します..." rm -rf /tmp/* else - echo "不明なパッケージマネージャー!" + echo "不明なパッケージマネージャーです!" return fi return @@ -4266,9 +4694,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4278,8 +4705,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4291,31 +4718,38 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } set_dns_ui() { root_use -send_stats "DNSを最適化します" +send_stats "DNSの最適化" while true; do clear - echo "DNSアドレスを最適化します" + echo "DNSアドレスを最適化する" echo "------------------------" echo "現在のDNSアドレス" cat /etc/resolv.conf echo "------------------------" echo "" - echo "1。外国DNS最適化:" + echo "1. 外部 DNS の最適化:" echo " v4: 1.1.1.1 8.8.8.8" echo " v6: 2606:4700:4700::1111 2001:4860:4860::8888" - echo "2。国内のDNS最適化:" + echo "2.国内DNSの最適化:" echo " v4: 223.5.5.5 183.60.83.19" echo " v6: 2400:3200::1 2400:da00::6666" - echo "3。DNS構成を手動で編集します" + echo "3. DNS 構成を手動で編集する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" Limiting + read -e -p "選択肢を入力してください:" Limiting case "$Limiting" in 1) local dns1_ipv4="1.1.1.1" @@ -4323,7 +4757,7 @@ while true; do local dns1_ipv6="2606:4700:4700::1111" local dns2_ipv6="2001:4860:4860::8888" set_dns - send_stats "外国のDNS最適化" + send_stats "外部DNSの最適化" ;; 2) local dns1_ipv4="223.5.5.5" @@ -4331,12 +4765,14 @@ while true; do local dns1_ipv6="2400:3200::1" local dns2_ipv6="2400:da00::6666" set_dns - send_stats "国内のDNS最適化" + send_stats "国内DNS最適化" ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf - send_stats "DNS構成を手動で編集します" + chattr +i /etc/resolv.conf + send_stats "DNS 構成を手動で編集する" ;; *) break @@ -4359,13 +4795,13 @@ correct_ssh_config() { local sshd_config="/etc/ssh/sshd_config" - # PasswordAuthenticationが見つかった場合は、はいに設定します + # 見つかった場合は、PasswordAuthentication が Yes に設定されます if grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" fi - # 発見された場合、pubkeyauthenticationはyesに設定されています + # 見つかった場合、PubkeyAuthentication は Yes に設定されます if grep -Eq "^PubkeyAuthentication\s+yes" "$sshd_config"; then sed -i -e 's/^\s*#\?\s*PermitRootLogin .*/PermitRootLogin prohibit-password/' \ -e 's/^\s*#\?\s*PasswordAuthentication .*/PasswordAuthentication no/' \ @@ -4373,7 +4809,7 @@ correct_ssh_config() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' "$sshd_config" fi - # PasswordAuthenticationもPubKeyAuthenticationが一致しない場合は、デフォルト値を設定します + # PasswordAuthentication も PubkeyAuthentication も一致しない場合にデフォルト値を設定します if ! grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config" && ! grep -Eq "^PubkeyAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" @@ -4384,7 +4820,7 @@ correct_ssh_config() { new_ssh_port() { - # バックアップSSH構成ファイル + # SSH設定ファイルをバックアップする cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sed -i 's/^\s*#\?\s*Port/Port/' /etc/ssh/sshd_config @@ -4397,7 +4833,7 @@ new_ssh_port() { open_port $new_port remove iptables-persistent ufw firewalld iptables-services > /dev/null 2>&1 - echo "SSHポートは次のように変更されています。$new_port" + echo "SSH ポートは次のように変更されました。$new_port" sleep 1 @@ -4415,7 +4851,7 @@ add_sshkey() { chmod 600 ~/.ssh/authorized_keys ip_address - echo -e "秘密のキー情報が生成されました。必ずコピーして保存してください。${gl_huang}${ipv4_address}_ssh.key${gl_bai}将来のSSHログイン用のファイル" + echo -e "秘密鍵情報が生成されました。必ずコピーして保存してください。として保存できます${gl_huang}${ipv4_address}_ssh.key${gl_bai}今後の SSH ログイン用のファイル" echo "--------------------------------" cat ~/.ssh/sshkey @@ -4427,17 +4863,17 @@ add_sshkey() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}ルートプライベートキーログインが有効になり、ルートパスワードログインが閉じられ、再接続が有効になります${gl_bai}" + echo -e "${gl_lv}ROOT 秘密キー ログインがオンになり、ROOT パスワード ログインがオフになり、再接続が有効になります。${gl_bai}" } import_sshkey() { - read -e -p "SSH公開キーの内容を入力してください(通常は「SSH-RSA」または「SSH-ED25519」から始まります):" public_key + read -e -p "SSH 公開キーの内容を入力してください (通常は「ssh-rsa」または「ssh-ed25519」で始まります):" public_key if [[ -z "$public_key" ]]; then - echo -e "${gl_hong}エラー:公開キーのコンテンツは入力されませんでした。${gl_bai}" + echo -e "${gl_hong}エラー: 公開キーの内容が入力されていません。${gl_bai}" return 1 fi @@ -4455,7 +4891,7 @@ import_sshkey() { rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}公開キーが正常にインポートされ、ルート秘密キーログインが有効になり、ルートパスワードログインが閉じられ、再接続が有効になります${gl_bai}" + echo -e "${gl_lv}公開キーは正常にインポートされ、ROOT 秘密キーのログインが有効になり、ROOT パスワードのログインが閉じられました。再接続が有効になります。${gl_bai}" } @@ -4464,26 +4900,26 @@ import_sshkey() { add_sshpasswd() { -echo "ルートパスワードを設定します" +echo "ROOTパスワードを設定する" passwd sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config; sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config; rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh -echo -e "${gl_lv}ルートログインがセットアップされます!${gl_bai}" +echo -e "${gl_lv}ROOTログインの設定が完了しました!${gl_bai}" } root_use() { clear -[ "$EUID" -ne 0 ] && echo -e "${gl_huang}ヒント:${gl_bai}この機能には、ルートユーザーを実行する必要があります!" && break_end && kejilion +[ "$EUID" -ne 0 ] && echo -e "${gl_huang}ヒント:${gl_bai}この機能を実行するには root ユーザーが必要です。" && break_end && kejilion } dd_xitong() { - send_stats "システムを再インストールします" + send_stats "システムを再インストールする" dd_xitong_MollyLau() { wget --no-check-certificate -qO InstallNET.sh "${gh_proxy}raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh" && chmod a+x InstallNET.sh @@ -4494,44 +4930,47 @@ dd_xitong() { } dd_xitong_1() { - echo -e "再インストール後の初期ユーザー名:${gl_huang}root${gl_bai}最初のパスワード:${gl_huang}LeitboGi0ro${gl_bai}初期ポート:${gl_huang}22${gl_bai}" - echo -e "任意のキーを押して続行します..." + echo -e "再インストール後の初期ユーザー名:${gl_huang}root${gl_bai}初期パスワード:${gl_huang}LeitboGi0ro${gl_bai}初期ポート:${gl_huang}22${gl_bai}" + echo -e "${gl_huang}再インストール後は、暴力的な侵入を防ぐため、初期パスワードを適時に変更してください。パスワードを変更するには、コマンドラインに passwd と入力します。${gl_bai}" + echo -e "続行するには任意のキーを押してください..." read -n 1 -s -r -p "" install wget dd_xitong_MollyLau } dd_xitong_2() { - echo -e "再インストール後の初期ユーザー名:${gl_huang}Administrator${gl_bai}最初のパスワード:${gl_huang}Teddysun.com${gl_bai}初期ポート:${gl_huang}3389${gl_bai}" - echo -e "任意のキーを押して続行します..." + echo -e "再インストール後の初期ユーザー名:${gl_huang}Administrator${gl_bai}初期パスワード:${gl_huang}Teddysun.com${gl_bai}初期ポート:${gl_huang}3389${gl_bai}" + echo -e "続行するには任意のキーを押してください..." read -n 1 -s -r -p "" install wget dd_xitong_MollyLau } dd_xitong_3() { - echo -e "再インストール後の初期ユーザー名:${gl_huang}root${gl_bai}最初のパスワード:${gl_huang}123@@@${gl_bai}初期ポート:${gl_huang}22${gl_bai}" - echo -e "任意のキーを押して続行します..." + echo -e "再インストール後の初期ユーザー名:${gl_huang}root${gl_bai}初期パスワード:${gl_huang}123@@@${gl_bai}初期ポート:${gl_huang}22${gl_bai}" + echo -e "続行するには任意のキーを押してください..." read -n 1 -s -r -p "" dd_xitong_bin456789 } dd_xitong_4() { - echo -e "再インストール後の初期ユーザー名:${gl_huang}Administrator${gl_bai}最初のパスワード:${gl_huang}123@@@${gl_bai}初期ポート:${gl_huang}3389${gl_bai}" - echo -e "任意のキーを押して続行します..." + echo -e "再インストール後の初期ユーザー名:${gl_huang}Administrator${gl_bai}初期パスワード:${gl_huang}123@@@${gl_bai}初期ポート:${gl_huang}3389${gl_bai}" + echo -e "続行するには任意のキーを押してください..." read -n 1 -s -r -p "" dd_xitong_bin456789 } while true; do root_use - echo "システムを再インストールします" + echo "システムを再インストールする" echo "--------------------------------" - echo -e "${gl_hong}知らせ:${gl_bai}再インストールは接触を失う危険であり、心配している人はそれを注意して使用する必要があります。再インストールには15分かかると予想されます。事前にデータをバックアップしてください。" - echo -e "${gl_hui}スクリプトサポートについては、MollylauとBin456789に感謝します!${gl_bai} " + echo -e "${gl_hong}知らせ:${gl_bai}再インストールすると接続が切れる可能性がありますので、不安な方はご注意ください。再インストールには 15 分程度かかることが予想されますので、事前にデータをバックアップしてください。" + echo -e "${gl_hui}スクリプトをサポートしてくれたボス bin456789 とボス leitbogioro に感謝します。${gl_bai} " + echo -e "${gl_hui}bin456789 プロジェクトのアドレス: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro プロジェクトのアドレス: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4544,68 +4983,71 @@ dd_xitong() { echo "------------------------" echo "31. Alpine Linux 32. Arch Linux" echo "33. Kali Linux 34. openEuler" - echo "35。OpenSuseTumbleWeed36。FNOSFEINIU PUBLIC BETAバージョン" + echo "35. openSUSE Tumbleweed 36. fnos Feiniu パブリックベータ版" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "再インストールするシステムを選択してください:" sys_choice + read -e -p "再インストールするシステムを選択してください:" sys_choice case "$sys_choice" in + + 1) - send_stats "Debian 12を再インストールします" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "debian13を再インストールする" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "Debian 11を再インストールします" + send_stats "debian12を再インストールする" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "Debian 10を再インストールします" + send_stats "debian11を再インストールする" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "Debian 9を再インストールします" + send_stats "debian10を再インストールする" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; 11) - send_stats "Ubuntu 24.04を再インストールします" + send_stats "ubuntu 24.04を再インストールします" dd_xitong_1 bash InstallNET.sh -ubuntu 24.04 reboot exit ;; 12) - send_stats "Ubuntu 22.04を再インストールします" + send_stats "ubuntu 22.04を再インストールします" dd_xitong_1 bash InstallNET.sh -ubuntu 22.04 reboot exit ;; 13) - send_stats "Ubuntu 20.04を再インストールします" + send_stats "ubuntu 20.04を再インストールします" dd_xitong_1 bash InstallNET.sh -ubuntu 20.04 reboot exit ;; 14) - send_stats "Ubuntu 18.04を再インストールします" + send_stats "ubuntu 18.04を再インストールします" dd_xitong_1 bash InstallNET.sh -ubuntu 18.04 reboot @@ -4614,7 +5056,7 @@ dd_xitong() { 21) - send_stats "Rockylinux10を再インストールします" + send_stats "Rockylinux10を再インストールする" dd_xitong_3 bash reinstall.sh rocky reboot @@ -4622,7 +5064,7 @@ dd_xitong() { ;; 22) - send_stats "Rockylinux9を再インストールします" + send_stats "Rockylinux9 を再インストールする" dd_xitong_3 bash reinstall.sh rocky 9 reboot @@ -4630,7 +5072,7 @@ dd_xitong() { ;; 23) - send_stats "alma10を再インストールします" + send_stats "alma10を再インストールする" dd_xitong_3 bash reinstall.sh almalinux reboot @@ -4638,7 +5080,7 @@ dd_xitong() { ;; 24) - send_stats "alma9を再インストールします" + send_stats "alma9を再インストールする" dd_xitong_3 bash reinstall.sh almalinux 9 reboot @@ -4646,7 +5088,7 @@ dd_xitong() { ;; 25) - send_stats "Oracle10を再インストールします" + send_stats "oracle10を再インストールする" dd_xitong_3 bash reinstall.sh oracle reboot @@ -4654,7 +5096,7 @@ dd_xitong() { ;; 26) - send_stats "Oracle9を再インストールします" + send_stats "oracle9を再インストールする" dd_xitong_3 bash reinstall.sh oracle 9 reboot @@ -4662,7 +5104,7 @@ dd_xitong() { ;; 27) - send_stats "Fedora42を再インストールします" + send_stats "fedora42を再インストールする" dd_xitong_3 bash reinstall.sh fedora reboot @@ -4670,7 +5112,7 @@ dd_xitong() { ;; 28) - send_stats "Fedora41を再インストールします" + send_stats "fedora41を再インストールする" dd_xitong_3 bash reinstall.sh fedora 41 reboot @@ -4678,7 +5120,7 @@ dd_xitong() { ;; 29) - send_stats "CENTOS10を再インストールします" + send_stats "centos10を再インストールする" dd_xitong_3 bash reinstall.sh centos 10 reboot @@ -4686,7 +5128,7 @@ dd_xitong() { ;; 30) - send_stats "CENTOS9を再インストールします" + send_stats "centos9を再インストールする" dd_xitong_3 bash reinstall.sh centos 9 reboot @@ -4694,7 +5136,7 @@ dd_xitong() { ;; 31) - send_stats "アルパインを再インストールします" + send_stats "アルパインを再インストールする" dd_xitong_1 bash InstallNET.sh -alpine reboot @@ -4702,7 +5144,7 @@ dd_xitong() { ;; 32) - send_stats "アーチを再インストールします" + send_stats "アーチを再インストールする" dd_xitong_3 bash reinstall.sh arch reboot @@ -4710,7 +5152,7 @@ dd_xitong() { ;; 33) - send_stats "Kaliを再インストールします" + send_stats "kaliを再インストールする" dd_xitong_3 bash reinstall.sh kali reboot @@ -4718,7 +5160,7 @@ dd_xitong() { ;; 34) - send_stats "Openeulerを再インストールします" + send_stats "オープニューラーを再インストールする" dd_xitong_3 bash reinstall.sh openeuler reboot @@ -4726,7 +5168,7 @@ dd_xitong() { ;; 35) - send_stats "OpenSuseを再インストールします" + send_stats "opensuse を再インストールする" dd_xitong_3 bash reinstall.sh opensuse reboot @@ -4734,30 +5176,31 @@ dd_xitong() { ;; 36) - send_stats "飛ぶ牛をリロードします" + send_stats "Feiniu を再インストールする" dd_xitong_3 bash reinstall.sh fnos reboot exit ;; - 41) - send_stats "Windows11を再インストールします" + send_stats "Windows 11を再インストールする" dd_xitong_2 bash InstallNET.sh -windows 11 -lang "cn" reboot exit ;; + 42) dd_xitong_2 - send_stats "Windows 10を再インストールします" + send_stats "Windows 10を再インストールする" bash InstallNET.sh -windows 10 -lang "cn" reboot exit ;; + 43) - send_stats "Windows 7を再インストールします" + send_stats "Windows7を再インストールする" dd_xitong_4 bash reinstall.sh windows --iso="https://drive.massgrave.dev/cn_windows_7_professional_with_sp1_x64_dvd_u_677031.iso" --image-name='Windows 7 PROFESSIONAL' reboot @@ -4765,29 +5208,31 @@ dd_xitong() { ;; 44) - send_stats "Windows Server 22を再インストールします" + send_stats "Windowsサーバー25を再インストールします" dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "Windows Server 19を再インストールします" + send_stats "Windowsサーバー22を再インストールします" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "Windows Server 16を再インストールします" + send_stats "Windowsサーバー19を再インストールします" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; 47) - send_stats "Windows11アームを再インストールします" + send_stats "Windows11 ARMを再インストールする" dd_xitong_4 bash reinstall.sh dd --img https://r2.hotdog.eu.org/win11-arm-with-pagefile-15g.xz reboot @@ -4804,7 +5249,7 @@ dd_xitong() { bbrv3() { root_use - send_stats "BBRV3管理" + send_stats "bbrv3管理" local cpu_arch=$(uname -m) if [ "$cpu_arch" = "aarch64" ]; then @@ -4817,17 +5262,17 @@ bbrv3() { while true; do clear local kernel_version=$(uname -r) - echo "XanmodのBBRV3カーネルをインストールしました" - echo "現在のカーネルバージョン:$kernel_version" + echo "xanmod の BBRv3 カーネルがインストールされている" + echo "現在のカーネル バージョン:$kernel_version" echo "" echo "カーネル管理" echo "------------------------" - echo "1。BBRV3カーネルを更新する2。BBRV3カーネルをアンインストールします" + echo "1. BBRv3 カーネルを更新します。 2. BBRv3 カーネルをアンインストールします。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) @@ -4837,7 +5282,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # ステップ3:リポジトリを追加します + # ステップ 3: リポジトリを追加する echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4846,7 +5291,7 @@ bbrv3() { apt update -y apt install -y linux-xanmod-x64v$version - echo "Xanmodカーネルが更新されました。再起動後に有効になります" + echo "XanMod カーネルが更新されました。再起動後に有効になります" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* @@ -4856,7 +5301,7 @@ bbrv3() { 2) apt purge -y 'linux-*xanmod1*' update-grub - echo "Xanmodカーネルはアンインストールされています。再起動後に有効になります" + echo "XanMod カーネルがアンインストールされました。再起動後に有効になります" server_reboot ;; @@ -4869,14 +5314,13 @@ bbrv3() { else clear - echo "BBR3加速度をセットアップします" - echo "ビデオの紹介:https://www.bilibili.com/video/bv14k421x7bs?t=0.1" + echo "BBR3アクセラレーションの設定" + echo "ビデオ紹介: https://www.bilibili.com/video/BV14K421x7BS?t=0.1" echo "------------------------------------------------" - echo "Debian/Ubuntuのみをサポートします" - echo "データをバックアップしてください。Linuxカーネルをアップグレードできるようになります。" - echo "VPSには512mのメモリがあります。メモリが不十分なため、接触の欠落を防ぐために、事前に1G仮想メモリを追加してください!" + echo "Debian/Ubuntu のみをサポートします" + echo "データをバックアップしてください。Linux カーネルをアップグレードして BBR3 を有効にします。" echo "------------------------------------------------" - read -e -p "必ず続行しますか? (y/n):" choice + read -e -p "続行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) @@ -4884,12 +5328,12 @@ bbrv3() { if [ -r /etc/os-release ]; then . /etc/os-release if [ "$ID" != "debian" ] && [ "$ID" != "ubuntu" ]; then - echo "現在の環境はそれをサポートせず、DebianとUbuntuシステムのみをサポートしています" + echo "現在の環境では対応しておりません。 Debian および Ubuntu システムのみがサポートされています。" break_end linux_Settings fi else - echo "オペレーティングシステムの種類を決定できません" + echo "オペレーティング システムの種類を特定できません" break_end linux_Settings fi @@ -4900,7 +5344,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # ステップ3:リポジトリを追加します + # ステップ 3: リポジトリを追加する echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4911,7 +5355,7 @@ bbrv3() { bbr_on - echo "Xanmodカーネルがインストールされ、BBR3が正常に有効になります。再起動後に有効になります" + echo "XanMod カーネルがインストールされ、BBR3 が正常に有効になります。再起動後に有効になります" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* server_reboot @@ -4921,7 +5365,7 @@ bbrv3() { echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac fi @@ -4930,40 +5374,40 @@ bbrv3() { elrepo_install() { - # Elrepo GPG公開キーをインポートします - echo "Elrepo GPG公開キーをインポートしてください..." + # ELRepo GPG 公開キーをインポートする + echo "ELRepo GPG 公開キーをインポートします..." rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - # システムバージョンを検出します + # システムバージョンを確認する local os_version=$(rpm -q --qf "%{VERSION}" $(rpm -qf /etc/os-release) 2>/dev/null | awk -F '.' '{print $1}') local os_name=$(awk -F= '/^NAME/{print $2}' /etc/os-release) - # サポートされているオペレーティングシステムで実行されていることを確認してください + # サポートされているオペレーティング システムで実行されていることを確認してください if [[ "$os_name" != *"Red Hat"* && "$os_name" != *"AlmaLinux"* && "$os_name" != *"Rocky"* && "$os_name" != *"Oracle"* && "$os_name" != *"CentOS"* ]]; then - echo "サポートされていないオペレーティングシステム:$os_name" + echo "サポートされていないオペレーティング システム:$os_name" break_end linux_Settings fi - # 検出されたオペレーティングシステム情報を印刷します - echo "検出されたオペレーティングシステム:$os_name $os_version" - # システムバージョンに応じて、対応するElrepo Warehouse構成をインストールする + # 検出されたオペレーティング システム情報を印刷する + echo "検出されたオペレーティング システム:$os_name $os_version" + # システムのバージョンに応じて、対応する ELRepo ウェアハウス構成をインストールします。 if [[ "$os_version" == 8 ]]; then - echo "Elrepoリポジトリ構成(バージョン8)をインストールしてください..." + echo "ELRepo リポジトリ構成 (バージョン 8) をインストールしています..." yum -y install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm elif [[ "$os_version" == 9 ]]; then - echo "Elrepoリポジトリ構成(バージョン9)をインストールしてください..." + echo "ELRepo リポジトリ構成 (バージョン 9) をインストールしています..." yum -y install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm elif [[ "$os_version" == 10 ]]; then - echo "Elrepoリポジトリ構成(バージョン10)をインストールしてください..." + echo "ELRepo リポジトリ構成 (バージョン 10) をインストールしています..." yum -y install https://www.elrepo.org/elrepo-release-10.el10.elrepo.noarch.rpm else - echo "サポートされていないシステムバージョン:$os_version" + echo "サポートされていないシステム バージョン:$os_version" break_end linux_Settings fi - # Elrepoカーネルリポジトリを有効にし、最新のメインラインカーネルをインストールします - echo "Elrepoカーネルリポジトリを有効にし、最新のメインラインカーネルをインストールしてください..." + # ELRepo カーネル リポジトリを有効にし、最新のメインライン カーネルをインストールします。 + echo "ELRepo カーネル リポジトリを有効にし、最新のメインライン カーネルをインストールします..." # yum -y --enablerepo=elrepo-kernel install kernel-ml yum --nogpgcheck -y --enablerepo=elrepo-kernel install kernel-ml - echo "Elrepoリポジトリ構成がインストールされ、最新のメインラインカーネルに更新されます。" + echo "ELRepo リポジトリ構成をインストールし、最新のメインライン カーネルに更新しました。" server_reboot } @@ -4971,37 +5415,37 @@ elrepo_install() { elrepo() { root_use - send_stats "レッドハットカーネル管理" + send_stats "Red Hat カーネル管理" if uname -r | grep -q 'elrepo'; then while true; do clear kernel_version=$(uname -r) - echo "Elrepo Kernelをインストールしました" - echo "現在のカーネルバージョン:$kernel_version" + echo "elrepo カーネルがインストールされています" + echo "現在のカーネル バージョン:$kernel_version" echo "" echo "カーネル管理" echo "------------------------" - echo "1. Elrepo Kernel 2を更新します。ElrepoKernelをアンインストールします" + echo "1. elrepo カーネルを更新します。 2. elrepo カーネルをアンインストールします。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps elrepo_install - send_stats "Red Hatカーネルを更新します" + send_stats "Red Hat カーネルを更新する" server_reboot ;; 2) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps - echo "Elrepoカーネルはアンインストールされています。再起動後に有効になります" - send_stats "レッドハットカーネルをアンインストールします" + echo "elrepo カーネルがアンインストールされました。再起動後に有効になります" + send_stats "Red Hat カーネルをアンインストールする" server_reboot ;; @@ -5014,26 +5458,26 @@ elrepo() { else clear - echo "データをバックアップしてください、そしてあなたのためにLinuxカーネルをアップグレードします" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1mh4y1w7qa?t=529.2" + echo "データをバックアップしてください。Linux カーネルをアップグレードします。" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1mH4y1w7qA?t=529.2" echo "------------------------------------------------" - echo "レッドハットシリーズの分布のみをサポートしますCentos/Redhat/Alma/Rocky/Oracle" - echo "Linuxカーネルをアップグレードすると、システムのパフォーマンスとセキュリティが向上する可能性があります。条件が許可され、生産環境を慎重にアップグレードする場合は、試してみることをお勧めします!" + echo "Red Hat シリーズのディストリビューション CentOS/RedHat/Alma/Rocky/oracle のみをサポートします" + echo "Linux カーネルをアップグレードすると、システムのパフォーマンスとセキュリティが向上します。可能であれば試して、慎重に実稼働環境をアップグレードすることをお勧めします。" echo "------------------------------------------------" - read -e -p "必ず続行しますか? (y/n):" choice + read -e -p "続行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) check_swap elrepo_install - send_stats "Red Hatカーネルをアップグレードします" + send_stats "Red Hat カーネルをアップグレードする" server_reboot ;; [Nn]) echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac fi @@ -5044,7 +5488,7 @@ elrepo() { clamav_freshclam() { - echo -e "${gl_huang}ウイルスデータベースを更新してください...${gl_bai}" + echo -e "${gl_huang}ウイルスデータベースを更新しています...${gl_bai}" docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ @@ -5058,15 +5502,15 @@ clamav_scan() { return fi - echo -e "${gl_huang}スキャンディレクトリ$@...${gl_bai}" + echo -e "${gl_huang}ディレクトリ $@ をスキャンしています...${gl_bai}" - # マウントパラメーターを構築します + # ビルドマウントパラメータ local MOUNT_PARAMS="" for dir in "$@"; do MOUNT_PARAMS+="--mount type=bind,source=${dir},target=/mnt/host${dir} " done - # CLAMSCANコマンドパラメーターを作成します + # clamscan コマンドパラメータを構築する local SCAN_PARAMS="" for dir in "$@"; do SCAN_PARAMS+="/mnt/host${dir} " @@ -5075,8 +5519,8 @@ clamav_scan() { mkdir -p /home/docker/clamav/log/ > /dev/null 2>&1 > /home/docker/clamav/log/scan.log > /dev/null 2>&1 - # Dockerコマンドを実行します - docker run -it --rm \ + # Dockerコマンドを実行する + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5084,8 +5528,8 @@ clamav_scan() { clamav/clamav-debian:latest \ clamscan -r --log=/var/log/clamav/scan.log $SCAN_PARAMS - echo -e "${gl_lv}$@スキャンが完了し、ウイルスレポートが保存されます${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" - echo -e "${gl_lv}ウイルスがある場合は、お願いします${gl_huang}scan.log${gl_lv}ファイルで見つかったキーワードを検索して、ウイルスの場所を確認する${gl_bai}" + echo -e "${gl_lv}$@ 扫描完成,病毒报告存放在${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" + echo -e "${gl_lv}ウイルスがある場合はお願いします${gl_huang}scan.log${gl_lv}ファイル内で FOUND キーワードを検索して、ウイルスの場所を確認します。${gl_bai}" } @@ -5100,20 +5544,20 @@ clamav() { send_stats "ウイルススキャン管理" while true; do clear - echo "クラマブウイルススキャンツール" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1tqvze4eqm?t=0.1" + echo "Clamav ウイルス スキャン ツール" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1TqvZe4EQm?t=0.1" echo "------------------------" - echo "これは、主にさまざまな種類のマルウェアを検出および除去するために使用されるオープンソースのウイルス対策ソフトウェアツールです。" - echo "ウイルス、トロイの木馬、スパイウェア、悪意のあるスクリプト、その他の有害なソフトウェアを含む。" + echo "これは、主にさまざまな種類のマルウェアを検出して削除するために使用されるオープンソースのウイルス対策ソフトウェア ツールです。" + echo "ウイルス、トロイの木馬、スパイウェア、悪意のあるスクリプト、その他の有害なソフトウェアが含まれます。" echo "------------------------" - echo -e "${gl_lv}1。フルディスクスキャン${gl_bai} ${gl_huang}2.重要なディレクトリをスキャンします${gl_bai} ${gl_kjlan}3。カスタムディレクトリスキャン${gl_bai}" + echo -e "${gl_lv}1.フルスキャン${gl_bai} ${gl_huang}2. 重要なディレクトリをスキャンする${gl_bai} ${gl_kjlan}3. カスタムディレクトリスキャン${gl_bai}" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "フルディスクスキャン" + send_stats "フルスキャン" install_docker docker volume create clam_db > /dev/null 2>&1 clamav_freshclam @@ -5122,7 +5566,7 @@ clamav() { ;; 2) - send_stats "重要なディレクトリスキャン" + send_stats "重要なディレクトリのスキャン" install_docker docker volume create clam_db > /dev/null 2>&1 clamav_freshclam @@ -5131,7 +5575,7 @@ clamav() { ;; 3) send_stats "カスタムディレクトリスキャン" - read -e -p "スペースで区切られたスキャンにディレクトリを入力してください(例: /etc /var /usr /home /root):" directories + read -e -p "スキャンするディレクトリをスペースで区切って入力してください (例: /etc /var /usr /home /root):" directories install_docker clamav_freshclam clamav_scan $directories @@ -5148,9 +5592,9 @@ clamav() { -# 高性能モード最適化関数 +# ハイパフォーマンスモード最適化機能 optimize_high_performance() { - echo -e "${gl_lv}に切り替えます${tiaoyou_moshi}...${gl_bai}" + echo -e "${gl_lv}に切り替える${tiaoyou_moshi}...${gl_bai}" echo -e "${gl_lv}ファイル記述子を最適化します...${gl_bai}" ulimit -n 65535 @@ -5181,15 +5625,15 @@ optimize_high_performance() { sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null echo -e "${gl_lv}その他の最適化...${gl_bai}" - # レイテンシを減らすために、大きな透明なページを無効にします + # 透明な巨大ページを無効にして遅延を軽減する echo never > /sys/kernel/mm/transparent_hugepage/enabled - # 禁用 NUMA balancing + # NUMA バランシングを無効にする sysctl -w kernel.numa_balancing=0 2>/dev/null } -# イコライゼーションモード最適化関数 +# バランスモード最適化機能 optimize_balanced() { echo -e "${gl_lv}イコライゼーションモードに切り替えます...${gl_bai}" @@ -5222,17 +5666,17 @@ optimize_balanced() { sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null echo -e "${gl_lv}その他の最適化...${gl_bai}" - # 透明なページを復元します + # 透明な巨大ページを復元する echo always > /sys/kernel/mm/transparent_hugepage/enabled - # numaバランスを復元します + # NUMA バランスを復元する sysctl -w kernel.numa_balancing=1 2>/dev/null } -# デフォルト設定関数を復元します +# デフォルト設定に戻す機能 restore_defaults() { - echo -e "${gl_lv}デフォルト設定に復元します...${gl_bai}" + echo -e "${gl_lv}デフォルト設定に戻す...${gl_bai}" echo -e "${gl_lv}ファイル記述子を復元します...${gl_bai}" ulimit -n 1024 @@ -5244,7 +5688,7 @@ restore_defaults() { sysctl -w vm.overcommit_memory=0 2>/dev/null sysctl -w vm.min_free_kbytes=16384 2>/dev/null - echo -e "${gl_lv}ネットワーク設定を復元します...${gl_bai}" + echo -e "${gl_lv}ネットワーク設定をリセットします...${gl_bai}" sysctl -w net.core.rmem_max=212992 2>/dev/null sysctl -w net.core.wmem_max=212992 2>/dev/null sysctl -w net.core.netdev_max_backlog=1000 2>/dev/null @@ -5262,19 +5706,19 @@ restore_defaults() { echo -e "${gl_lv}CPU設定を復元します...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null - echo -e "${gl_lv}他の最適化を復元します...${gl_bai}" - # 透明なページを復元します + echo -e "${gl_lv}他の最適化を元に戻します...${gl_bai}" + # 透明な巨大ページを復元する echo always > /sys/kernel/mm/transparent_hugepage/enabled - # numaバランスを復元します + # NUMA バランスを復元する sysctl -w kernel.numa_balancing=1 2>/dev/null } -# ウェブサイトの構築最適化機能 +# Webサイト構築最適化機能 optimize_web_server() { - echo -e "${gl_lv}ウェブサイトの構築最適化モードに切り替えます...${gl_bai}" + echo -e "${gl_lv}ウェブサイト構築最適化モードに切り替えます...${gl_bai}" echo -e "${gl_lv}ファイル記述子を最適化します...${gl_bai}" ulimit -n 65535 @@ -5305,9 +5749,9 @@ optimize_web_server() { sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null echo -e "${gl_lv}その他の最適化...${gl_bai}" - # レイテンシを減らすために、大きな透明なページを無効にします + # 透明な巨大ページを無効にして遅延を軽減する echo never > /sys/kernel/mm/transparent_hugepage/enabled - # numaバランスを無効にします + # NUMA バランシングを無効にする sysctl -w kernel.numa_balancing=0 2>/dev/null @@ -5319,29 +5763,29 @@ Kernel_optimize() { while true; do clear send_stats "Linuxカーネルチューニング管理" - echo "Linuxシステムにおけるカーネルパラメーターの最適化" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1kb421j7yg?t=0.1" + echo "Linuxシステムのカーネルパラメータの最適化" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1Kb421J7yg?t=0.1" echo "------------------------------------------------" - echo "さまざまなシステムパラメーターチューニングモードが提供され、ユーザーは独自の使用シナリオに従って選択および切り替えることができます。" - echo -e "${gl_huang}ヒント:${gl_bai}生産環境では注意して使用してください!" + echo "さまざまなシステムパラメータチューニングモードを提供し、ユーザーは独自の使用シナリオに応じて切り替えることができます。" + echo -e "${gl_huang}ヒント:${gl_bai}本番環境では注意して使用してください。" echo "--------------------" - echo "1.高性能最適化モード:システムパフォーマンスを最大化し、ファイル記述子、仮想メモリ、ネットワーク設定、キャッシュ管理、CPU設定を最適化します。" - echo "2。バランスの取れた最適化モード:毎日の使用に適したパフォーマンスとリソース消費のバランス。" - echo "3.ウェブサイトの最適化モード:Webサイトサーバーを最適化して、接続処理機能、応答速度、全体的なパフォーマンスを並行します。" - echo "4。ライブブロードキャスト最適化モード:ライブブロードキャストストリーミングの特別なニーズを最適化して、遅延を減らし、伝送パフォーマンスを向上させます。" - echo "5。ゲームサーバーの最適化モード:ゲームサーバーを最適化して、同時処理機能と応答速度を改善します。" - echo "6.デフォルト設定を復元します:システム設定をデフォルトの構成に復元します。" + echo "1. ハイパフォーマンス最適化モード: システムのパフォーマンスを最大化し、ファイル記述子、仮想メモリ、ネットワーク設定、キャッシュ管理、CPU 設定を最適化します。" + echo "2. バランスのとれた最適化モード: パフォーマンスとリソース消費のバランスをとり、日常的な使用に適しています。" + echo "3. Web サイト最適化モード: Web サイトサーバーを最適化して、同時接続処理能力、応答速度、全体的なパフォーマンスを向上させます。" + echo "4. ライブ ブロードキャスト最適化モード: ライブ ストリーミングの特別なニーズを最適化し、遅延を削減し、送信パフォーマンスを向上させます。" + echo "5. ゲームサーバー最適化モード: ゲームサーバーを最適化して、同時処理能力と応答速度を向上させます。" + echo "6. デフォルト設定の復元: システム設定をデフォルト構成に復元します。" echo "--------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "--------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) cd ~ clear - local tiaoyou_moshi="高性能优化模式" + local tiaoyou_moshi="高性能最適化モード" optimize_high_performance - send_stats "高性能モードの最適化" + send_stats "ハイパフォーマンスモードの最適化" ;; 2) cd ~ @@ -5353,19 +5797,19 @@ Kernel_optimize() { cd ~ clear optimize_web_server - send_stats "ウェブサイトの最適化モデル" + send_stats "ウェブサイト最適化モード" ;; 4) cd ~ clear - local tiaoyou_moshi="直播优化模式" + local tiaoyou_moshi="ライブブロードキャスト最適化モード" optimize_high_performance - send_stats "ライブストリーミング最適化" + send_stats "ライブストリーミングの最適化" ;; 5) cd ~ clear - local tiaoyou_moshi="游戏服优化模式" + local tiaoyou_moshi="ゲームサーバー最適化モード" optimize_high_performance send_stats "ゲームサーバーの最適化" ;; @@ -5373,7 +5817,7 @@ Kernel_optimize() { cd ~ clear restore_defaults - send_stats "デフォルト設定を復元します" + send_stats "デフォルト設定を復元する" ;; *) break @@ -5400,7 +5844,7 @@ update_locale() { locale-gen echo "LANG=${lang}" > /etc/default/locale export LANG=${lang} - echo -e "${gl_lv}システム言語は次のように変更されています。$langSSHの再接続が有効になります。${gl_bai}" + echo -e "${gl_lv}システム言語は次のように変更されました。$lang有効にするには、SSH に再接続します。${gl_bai}" hash -r break_end @@ -5409,17 +5853,17 @@ update_locale() { install glibc-langpack-zh localectl set-locale LANG=${lang} echo "LANG=${lang}" | tee /etc/locale.conf - echo -e "${gl_lv}システム言語は次のように変更されています。$langSSHの再接続が有効になります。${gl_bai}" + echo -e "${gl_lv}システム言語は次のように変更されました。$lang有効にするには、SSH に再接続します。${gl_bai}" hash -r break_end ;; *) - echo "サポートされていないシステム:$ID" + echo "サポートされていないシステム:$ID" break_end ;; esac else - echo "サポートされていないシステム、システムタイプは認識できません。" + echo "サポートされていないシステムです。システムの種類を識別できません。" break_end fi } @@ -5429,29 +5873,29 @@ update_locale() { linux_language() { root_use -send_stats "システム言語を切り替えます" +send_stats "システム言語を切り替える" while true; do clear - echo "現在のシステム言語:$LANG" + echo "現在のシステム言語:$LANG" echo "------------------------" - echo "1。英語2。簡素化された中国語3。伝統的な中国語" + echo "1. 英語 2. 簡体字中国語 3. 繁体字中国語" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) update_locale "en_US.UTF-8" "en_US.UTF-8" - send_stats "英語に切り替えます" + send_stats "英語に切り替えてください" ;; 2) update_locale "zh_CN.UTF-8" "zh_CN.UTF-8" - send_stats "簡素化された中国人に切り替えます" + send_stats "簡体字中国語に切り替える" ;; 3) update_locale "zh_TW.UTF-8" "zh_TW.UTF-8" - send_stats "伝統的な中国人に切り替えます" + send_stats "繁体字中国語に切り替える" ;; *) break @@ -5473,7 +5917,7 @@ else echo "${bianse}" >> ~/.profile # source ~/.profile fi -echo -e "${gl_lv}変更が完了します。 SSHを再接続して変更を表示します!${gl_bai}" +echo -e "${gl_lv}変更が完了しました。 SSH に再接続して変更を確認してください。${gl_bai}" hash -r break_end @@ -5484,10 +5928,10 @@ break_end shell_bianse() { root_use - send_stats "コマンドラインの美化ツール" + send_stats "コマンドライン美化ツール" while true; do clear - echo "コマンドラインの美化ツール" + echo "コマンドライン美化ツール" echo "------------------------" echo -e "1. \033[1;32mroot \033[1;34mlocalhost \033[1;31m~ \033[0m${gl_bai}#" echo -e "2. \033[1;35mroot \033[1;36mlocalhost \033[1;33m~ \033[0m${gl_bai}#" @@ -5497,9 +5941,9 @@ shell_bianse() { echo -e "6. \033[1;33mroot \033[1;34mlocalhost \033[1;35m~ \033[0m${gl_bai}#" echo -e "7. root localhost ~ #" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) @@ -5544,7 +5988,7 @@ shell_bianse() { linux_trash() { root_use - send_stats "システムリサイクルステーション" + send_stats "システムのごみ箱" local bashrc_profile="/root/.bashrc" local TRASH_DIR="$HOME/.local/share/Trash/files" @@ -5553,23 +5997,23 @@ linux_trash() { local trash_status if ! grep -q "trash-put" "$bashrc_profile"; then - trash_status="${gl_hui}未启用${gl_bai}" + trash_status="${gl_hui}有効になっていません${gl_bai}" else - trash_status="${gl_lv}已启用${gl_bai}" + trash_status="${gl_lv}有効${gl_bai}" fi clear - echo -e "現在のリサイクルビン${trash_status}" - echo -e "有効になった後、RMによって削除されたファイルは、最初にリサイクルビンに入り、重要なファイルの誤った削除を防ぎます!" + echo -e "現在のごみ箱${trash_status}" + echo -e "有効にすると、重要なファイルを誤って削除することを防ぐために、rm によって削除されたファイルは最初にごみ箱に入れられます。" echo "------------------------------------------------" - ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "リサイクルビンは空です" + ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "ごみ箱が空です" echo "------------------------" - echo "1.リサイクルビン2を有効にします。リサイクルビンを閉じます" - echo "3。コンテンツを復元4。リサイクルビンをクリアします" + echo "1. ごみ箱を有効にする 2. ごみ箱を閉じる" + echo "3. コンテンツを復元する 4. ごみ箱を空にする" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) @@ -5577,7 +6021,7 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='trash-put'" >> "$bashrc_profile" source "$bashrc_profile" - echo "リサイクルビンが有効になり、削除されたファイルがリサイクルビンに移動されます。" + echo "ごみ箱が有効になっていると、削除されたファイルはごみ箱に移動されます。" sleep 2 ;; 2) @@ -5585,23 +6029,23 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='rm -i'" >> "$bashrc_profile" source "$bashrc_profile" - echo "リサイクルビンが閉じられ、ファイルが直接削除されます。" + echo "ごみ箱が閉じられ、ファイルは直接削除されます。" sleep 2 ;; 3) - read -e -p "復元するにはファイル名を入力してください。" file_to_restore + read -e -p "復元するファイル名を入力してください:" file_to_restore if [ -e "$TRASH_DIR/$file_to_restore" ]; then mv "$TRASH_DIR/$file_to_restore" "$HOME/" echo "$file_to_restoreホームディレクトリに復元されました。" else - echo "ファイルは存在しません。" + echo "ファイルが存在しません。" fi ;; 4) - read -e -p "リサイクルビンをクリアすることを確認しますか? [Y/N]:" confirm + read -e -p "ごみ箱を空にしてもよろしいですか? [y/n]:" confirm if [[ "$confirm" == "y" ]]; then trash-empty - echo "リサイクルビンがクリアされました。" + echo "ごみ箱が空になりました。" fi ;; *) @@ -5611,21 +6055,24 @@ linux_trash() { done } +linux_fav() { +send_stats "コマンドのお気に入り" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} - -# バックアップを作成します +# バックアップの作成 create_backup() { - send_stats "バックアップを作成します" + send_stats "バックアップの作成" local TIMESTAMP=$(date +"%Y%m%d%H%M%S") - # ユーザーにバックアップディレクトリを入力するように求めます - echo "バックアップ例を作成します:" - echo "- 単一のディレクトリをバックアップします: /var /www" - echo "- バックアップ複数のディレクトリ: /etc /home /var /log" - echo "-directEnterはデフォルトのディレクトリ( /etc /usr /home)を使用します" - read -r -p "ディレクトリを入力してバックアップしてください(複数のディレクトリがスペースで区切られています。直接入力する場合は、デフォルトのディレクトリを使用してください):" input + # ユーザーにバックアップ ディレクトリの入力を求めるプロンプトを表示する + echo "バックアップの作成例:" + echo "- 単一ディレクトリをバックアップします: /var/www" + echo "- 複数のディレクトリをバックアップします: /etc /home /var/log" + echo "- Enter キーを押して、デフォルトのディレクトリ (/etc /usr /home) を使用します。" + read -r -p "バックアップするディレクトリを入力してください (複数のディレクトリをスペースで区切って、Enter キーを押してデフォルトのディレクトリを使用します)。" input - # ユーザーがディレクトリを入力しない場合は、デフォルトのディレクトリを使用します + # ユーザーがディレクトリを入力しない場合は、デフォルトのディレクトリが使用されます。 if [ -z "$input" ]; then BACKUP_PATHS=( "/etc" # 配置文件和软件包配置 @@ -5633,11 +6080,11 @@ create_backup() { "/home" # 用户数据 ) else - # ユーザーが入力したディレクトリをスペースごとに配列に分離します + # ユーザーが配列に入力したディレクトリをスペースで区切ります。 IFS=' ' read -r -a BACKUP_PATHS <<< "$input" fi - # バックアップファイルプレフィックスを生成します + # バックアップ ファイルのプレフィックスを生成する local PREFIX="" for path in "${BACKUP_PATHS[@]}"; do # ディレクトリ名を抽出し、スラッシュを削除します @@ -5648,77 +6095,77 @@ create_backup() { # 最後のアンダースコアを削除します local PREFIX=${PREFIX%_} - # バックアップファイル名を生成します + # バックアップファイル名の生成 local BACKUP_NAME="${PREFIX}_$TIMESTAMP.tar.gz" - # ユーザーが選択したディレクトリを印刷します - echo "選択したバックアップディレクトリは次のとおりです。" + # ユーザーが選択した印刷ディレクトリ + echo "選択したバックアップ ディレクトリは次のとおりです。" for path in "${BACKUP_PATHS[@]}"; do echo "- $path" done - # バックアップを作成します - echo "バックアップを作成します$BACKUP_NAME..." + # バックアップの作成 + echo "バックアップの作成$BACKUP_NAME..." install tar tar -czvf "$BACKUP_DIR/$BACKUP_NAME" "${BACKUP_PATHS[@]}" - # コマンドが成功しているかどうかを確認してください + # コマンドが成功したかどうかを確認する if [ $? -eq 0 ]; then - echo "バックアップは正常に作成されました:$BACKUP_DIR/$BACKUP_NAME" + echo "バックアップが正常に作成されました:$BACKUP_DIR/$BACKUP_NAME" else - echo "バックアップの作成に失敗しました!" + echo "バックアップの作成に失敗しました!" exit 1 fi } -# バックアップを復元します +# バックアップを復元する restore_backup() { - send_stats "バックアップを復元します" - # 復元するバックアップを選択します - read -e -p "復元するには、バックアップファイル名を入力してください。" BACKUP_NAME + send_stats "バックアップを復元する" + # 復元するバックアップを選択してください + read -e -p "復元するバックアップ ファイル名を入力してください:" BACKUP_NAME - # バックアップファイルが存在するかどうかを確認します + # バックアップファイルが存在するか確認する if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then - echo "バックアップファイルは存在しません!" + echo "バックアップファイルが存在しません!" exit 1 fi - echo "バックアップの回復$BACKUP_NAME..." + echo "バックアップの復元$BACKUP_NAME..." tar -xzvf "$BACKUP_DIR/$BACKUP_NAME" -C / if [ $? -eq 0 ]; then - echo "バックアップと復元を正常に!" + echo "バックアップと復元が成功しました。" else - echo "バックアップリカバリに失敗しました!" + echo "バックアップ復元に失敗しました!" exit 1 fi } -# バックアップをリストします +# バックアップの一覧表示 list_backups() { - echo "利用可能なバックアップ:" + echo "利用可能なバックアップ:" ls -1 "$BACKUP_DIR" } -# バックアップを削除します +# バックアップの削除 delete_backup() { - send_stats "バックアップを削除します" + send_stats "バックアップの削除" - read -e -p "削除するには、バックアップファイル名を入力してください。" BACKUP_NAME + read -e -p "削除するバックアップ ファイル名を入力してください:" BACKUP_NAME - # バックアップファイルが存在するかどうかを確認します + # バックアップファイルが存在するか確認する if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then - echo "バックアップファイルは存在しません!" + echo "バックアップファイルが存在しません!" exit 1 fi - # バックアップを削除します + # バックアップの削除 rm -f "$BACKUP_DIR/$BACKUP_NAME" if [ $? -eq 0 ]; then - echo "バックアップは正常に削除されました!" + echo "バックアップが正常に削除されました。" else - echo "バックアップの削除が失敗しました!" + echo "バックアップの削除に失敗しました!" exit 1 fi } @@ -5734,18 +6181,18 @@ linux_backup() { echo "------------------------" list_backups echo "------------------------" - echo "1.バックアップを作成する2。バックアップを復元3。バックアップを削除します" + echo "1. バックアップの作成 2. バックアップの復元 3. バックアップの削除" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) create_backup ;; 2) restore_backup ;; 3) delete_backup ;; *) break ;; esac - read -e -p "Enterを押して続行します..." + read -e -p "Enter を押して続行します..." done } @@ -5757,56 +6204,56 @@ linux_backup() { -# 接続リストを表示します +# 接続リストを表示 list_connections() { - echo "接続の保存:" + echo "保存された接続:" echo "------------------------" cat "$CONFIG_FILE" | awk -F'|' '{print NR " - " $1 " (" $2 ")"}' echo "------------------------" } -# 新しい接続を追加します +# 新しい接続を追加 add_connection() { - send_stats "新しい接続を追加します" - echo "新しい接続を作成する例:" - echo "- 接続名:my_server" - echo "- IPアドレス:192.168.1.100" - echo "- ユーザー名:root" - echo "- ポート:22" + send_stats "新しい接続を追加" + echo "新しい接続を作成する例:" + echo "- 接続名: my_server" + echo "- IP アドレス: 192.168.1.100" + echo "- ユーザー名: root" + echo "- ポート: 22" echo "------------------------" - read -e -p "接続名を入力してください:" name - read -e -p "IPアドレスを入力してください:" ip - read -e -p "ユーザー名(デフォルト:root)を入力してください:" user + read -e -p "接続名を入力してください:" name + read -e -p "IP アドレスを入力してください:" ip + read -e -p "ユーザー名を入力してください (デフォルト: root):" user local user=${user:-root} # 如果用户未输入,则使用默认值 root - read -e -p "ポート番号を入力してください(デフォルト:22):" port + read -e -p "ポート番号を入力してください (デフォルト: 22):" port local port=${port:-22} # 如果用户未输入,则使用默认值 22 - echo "認証方法を選択してください:" - echo "1。パスワード" - echo "2。キー" - read -e -p "選択(1/2)を入力してください:" auth_choice + echo "認証方法を選択してください:" + echo "1. パスワード" + echo "2. キー" + read -e -p "選択肢を入力してください (1/2):" auth_choice case $auth_choice in 1) - read -s -p "パスワードを入力してください:" password_or_key + read -s -p "パスワードを入力してください:" password_or_key echo # 换行 ;; 2) - echo "キーコンテンツを貼り付けてください(貼り付け後に2回Enterを押します)を押してください):" + echo "キーの内容を貼り付けてください (貼り付け後に Enter を 2 回押します)。" local password_or_key="" while IFS= read -r line; do - # 入力が空で、キーコンテンツにすでに開始が含まれている場合、入力は終了します + # 入力が空行で、キーの内容にすでに先頭が含まれている場合は、入力を終了します if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # それが最初の行であるか、キーコンテンツが入力されている場合は、さらに追加し続けます + # それが最初の行である場合、またはすでにキーコンテンツの入力を開始している場合は、追加を続けます。 if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then local password_or_key+="${line}"$'\n' fi done - # キーコンテンツのかどうかを確認してください + # キーコンテンツかどうかを確認する if [[ "$password_or_key" == *"-----BEGIN"* && "$password_or_key" == *"PRIVATE KEY-----"* ]]; then local key_file="$KEY_DIR/$name.key" echo -n "$password_or_key" > "$key_file" @@ -5815,77 +6262,77 @@ add_connection() { fi ;; *) - echo "無効な選択!" + echo "無効な選択です!" return ;; esac echo "$name|$ip|$user|$port|$password_or_key" >> "$CONFIG_FILE" - echo "接続が保存されます!" + echo "接続が保存されました!" } -# 接続を削除します +# 接続の削除 delete_connection() { - send_stats "接続を削除します" - read -e -p "削除するには、接続番号を入力してください。" num + send_stats "接続の削除" + read -e -p "削除する接続番号を入力してください:" num local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "エラー:対応する接続は見つかりませんでした。" + echo "エラー: 対応する接続​​が見つかりません。" return fi IFS='|' read -r name ip user port password_or_key <<< "$connection" - # 接続がキーファイルを使用している場合、キーファイルを削除します + # 接続にキー ファイルが使用されている場合は、キー ファイルを削除します if [[ "$password_or_key" == "$KEY_DIR"* ]]; then rm -f "$password_or_key" fi sed -i "${num}d" "$CONFIG_FILE" - echo "接続が削除されました!" + echo "接続が削除されました!" } -# 接続を使用します +# 接続を使用する use_connection() { - send_stats "接続を使用します" - read -e -p "使用するには、接続番号を入力してください。" num + send_stats "接続を使用する" + read -e -p "使用する接続番号を入力してください:" num local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "エラー:対応する接続は見つかりませんでした。" + echo "エラー: 対応する接続​​が見つかりません。" return fi IFS='|' read -r name ip user port password_or_key <<< "$connection" - echo "接続$name ($ip)..." + echo "接続先$name ($ip)..." if [[ -f "$password_or_key" ]]; then - # キーに接続します + # キーを使用して接続する ssh -o StrictHostKeyChecking=no -i "$password_or_key" -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then - echo "接続に失敗しました!以下を確認してください。" - echo "1。キーファイルパスは正しいですか?$password_or_key" - echo "2。キーファイルの権限が正しいかどうか(600である必要があります)。" - echo "3.ターゲットサーバーがキーを使用してログインできるかどうか。" + echo "接続に失敗しました!以下の点をご確認ください。" + echo "1. キーファイルのパスは正しいですか?$password_or_key" + echo "2. キー ファイルのアクセス許可は正しいか (600 である必要があります)。" + echo "3. ターゲットサーバーがキーを使用したログインを許可するかどうか。" fi else - # パスワードで接続します + # パスワードを使用して接続する if ! command -v sshpass &> /dev/null; then - echo "エラー:SSHPassはインストールされていません。最初にSSHPassをインストールしてください。" - echo "インストール方法:" + echo "エラー: sshpass がインストールされていません。最初に sshpass をインストールしてください。" + echo "インストール方法:" echo " - Ubuntu/Debian: apt install sshpass" echo " - CentOS/RHEL: yum install sshpass" return fi sshpass -p "$password_or_key" ssh -o StrictHostKeyChecking=no -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then - echo "接続に失敗しました!以下を確認してください。" - echo "1.ユーザー名とパスワードが正しいかどうか。" - echo "2。ターゲットサーバーがパスワードログインを許可するかどうか。" - echo "3.ターゲットサーバーのSSHサービスが正常に実行されているかどうか。" + echo "接続に失敗しました!以下の点をご確認ください。" + echo "1. ユーザー名とパスワードは正しいですか?" + echo "2. ターゲットサーバーがパスワードログインを許可するかどうか。" + echo "3. 対象サーバのSSHサービスが正常に動作しているか。" fi fi } @@ -5897,7 +6344,7 @@ ssh_manager() { CONFIG_FILE="$HOME/.ssh_connections" KEY_DIR="$HOME/.ssh/ssh_manager_keys" - # 構成ファイルとキーディレクトリが存在するかどうかを確認し、それが存在しない場合は、それを作成します + # 設定ファイルとキーディレクトリが存在するかどうかを確認し、存在しない場合は作成します。 if [[ ! -f "$CONFIG_FILE" ]]; then touch "$CONFIG_FILE" fi @@ -5910,20 +6357,20 @@ ssh_manager() { while true; do clear echo "SSHリモート接続ツール" - echo "SSHを介して他のLinuxシステムに接続できます" + echo "SSH経由で他のLinuxシステムに接続可能" echo "------------------------" list_connections - echo "1.新しい接続を作成する2。接続を使用する3。接続を削除します" + echo "1. 新しい接続を作成します。 2. 接続を使用します。 3. 接続を削除します。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) add_connection ;; 2) use_connection ;; 3) delete_connection ;; 0) break ;; - *) echo "無効な選択、もう一度やり直してください。" ;; + *) echo "選択が無効です。もう一度お試しください。" ;; esac done } @@ -5939,137 +6386,137 @@ ssh_manager() { -# 利用可能なハードディスクパーティションをリストします +# 利用可能なハードディスクのパーティションをリストする list_partitions() { - echo "利用可能なハードディスクパーティション:" + echo "利用可能なハードドライブのパーティション:" lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT | grep -v "sr\|loop" } -# パーティションをマウントします +# パーティションをマウントする mount_partition() { - send_stats "パーティションをマウントします" - read -e -p "マウントするパーティション名を入力してください(たとえば、SDA1):" PARTITION + send_stats "パーティションをマウントする" + read -e -p "マウントするパーティションの名前を入力してください (例: sda1):" PARTITION - # パーティションが存在するかどうかを確認します + # パーティションが存在するかどうかを確認する if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then - echo "パーティションは存在しません!" + echo "パーティションが存在しません!" return fi - # パーティションが既にマウントされているかどうかを確認してください + # パーティションがマウントされているかどうかを確認する if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "パーティションはすでに取り付けられています!" + echo "パーティションが取り付けられました!" return fi - # マウントポイントを作成します + # マウントポイントの作成 MOUNT_POINT="/mnt/$PARTITION" mkdir -p "$MOUNT_POINT" - # パーティションをマウントします + # パーティションをマウントする mount "/dev/$PARTITION" "$MOUNT_POINT" if [ $? -eq 0 ]; then - echo "パーティションマウントに正常に:$MOUNT_POINT" + echo "パーティションは正常にマウントされました:$MOUNT_POINT" else - echo "パーティションマウントは失敗しました!" + echo "パーティションのマウントに失敗しました!" rmdir "$MOUNT_POINT" fi } -# パーティションをアンインストールします +# パーティションをアンマウントする unmount_partition() { - send_stats "パーティションをアンインストールします" - read -e -p "パーティション名(たとえば、SDA1)を入力してください。" PARTITION + send_stats "パーティションをアンマウントする" + read -e -p "アンマウントするパーティションの名前を入力してください (例: sda1):" PARTITION - # パーティションが既にマウントされているかどうかを確認してください + # パーティションがマウントされているかどうかを確認する MOUNT_POINT=$(lsblk -o MOUNTPOINT | grep -w "$PARTITION") if [ -z "$MOUNT_POINT" ]; then - echo "パーティションはマウントされていません!" + echo "パーティションがマウントされていません!" return fi - # パーティションをアンインストールします + # パーティションをアンマウントする umount "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "パーティションのアンインストールに正常に:$MOUNT_POINT" + echo "パーティションが正常にアンインストールされました:$MOUNT_POINT" rmdir "$MOUNT_POINT" else - echo "パーティションのアンインストールに失敗しました!" + echo "パーティションのアンインストールに失敗しました!" fi } -# マウントされたパーティションをリストします +# マウントされたパーティションをリストする list_mounted_partitions() { - echo "マウントされたパーティション:" + echo "マウントされたパーティション:" df -h | grep -v "tmpfs\|udev\|overlay" } -# フォーマットパーティション +# パーティションをフォーマットする format_partition() { - send_stats "フォーマットパーティション" - read -e -p "パーティション名を入力してフォーマット(たとえば、SDA1):" PARTITION + send_stats "パーティションをフォーマットする" + read -e -p "フォーマットするパーティションの名前を入力してください (例: sda1):" PARTITION - # パーティションが存在するかどうかを確認します + # パーティションが存在するかどうかを確認する if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then - echo "パーティションは存在しません!" + echo "パーティションが存在しません!" return fi - # パーティションが既にマウントされているかどうかを確認してください + # パーティションがマウントされているかどうかを確認する if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "パーティションがマウントされました。最初にアンインストールしてください!" + echo "パーティションはマウントされています。最初にアンマウントしてください。" return fi - # ファイルシステムタイプを選択します - echo "ファイルシステムタイプを選択してください:" + # ファイルシステムの種類を選択してください + echo "ファイル システムのタイプを選択してください:" echo "1. ext4" echo "2. xfs" echo "3. ntfs" echo "4. vfat" - read -e -p "選択を入力してください:" FS_CHOICE + read -e -p "選択肢を入力してください:" FS_CHOICE case $FS_CHOICE in 1) FS_TYPE="ext4" ;; 2) FS_TYPE="xfs" ;; 3) FS_TYPE="ntfs" ;; 4) FS_TYPE="vfat" ;; - *) echo "無効な選択!"; return ;; + *) echo "無効な選択です!"; return ;; esac - # フォーマットを確認します - read -e -p "フォーマットパーティション /dev /$PARTITIONのために$FS_TYPEそれですか? (y/n):" CONFIRM + # フォーマットの確認 + read -e -p "フォーマットされたパーティション /dev/ を確認します$PARTITIONのために$FS_TYPE? (y/n):" CONFIRM if [ "$CONFIRM" != "y" ]; then echo "操作はキャンセルされました。" return fi - # フォーマットパーティション - echo "パーティション /dev /のフォーマット /$PARTITIONのために$FS_TYPE ..." + # パーティションをフォーマットする + echo "パーティション /dev/ をフォーマットしています$PARTITIONのために$FS_TYPE ..." mkfs.$FS_TYPE "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "パーティション形式は成功しました!" + echo "パーティションが正常にフォーマットされました。" else - echo "パーティションのフォーマットが失敗しました!" + echo "パーティションのフォーマットに失敗しました!" fi } -# パーティションステータスを確認します +# パーティションのステータスを確認する check_partition() { - send_stats "パーティションステータスを確認します" - read -e -p "パーティション名を入力して確認してください(たとえばSDA1):" PARTITION + send_stats "パーティションのステータスを確認する" + read -e -p "確認するパーティション名を入力してください (例: sda1):" PARTITION - # パーティションが存在するかどうかを確認します + # パーティションが存在するかどうかを確認する if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then - echo "パーティションは存在しません!" + echo "パーティションが存在しません!" return fi - # パーティションステータスを確認します - echo "パーティション /dev /$PARTITION状態:" + # パーティションのステータスを確認する + echo "パーティション /dev/ を確認してください$PARTITION状態:" fsck "/dev/$PARTITION" } @@ -6078,17 +6525,17 @@ disk_manager() { send_stats "ハードディスク管理機能" while true; do clear - echo "ハードディスクパーティション管理" - echo -e "${gl_huang}この関数は、テスト期間中に内部的にテストされています。生産環境では使用しないでください。${gl_bai}" + echo "ハードドライブのパーティション管理" + echo -e "${gl_huang}この機能は内部テスト中であるため、運用環境では使用しないでください。${gl_bai}" echo "------------------------" list_partitions echo "------------------------" - echo "1。パーティションをマウント2。パーティションをアンインストールする3。マウントされたパーティションを表示" - echo "4。パーティション5をフォーマットします。パーティションステータスを確認します" + echo "1. パーティションをマウントします。 2. パーティションをアンマウントします。 3. マウントされたパーティションを表示します。" + echo "4. パーティションをフォーマットします。 5. パーティションのステータスを確認します。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) mount_partition ;; 2) unmount_partition ;; @@ -6097,64 +6544,64 @@ disk_manager() { 5) check_partition ;; *) break ;; esac - read -e -p "Enterを押して続行します..." + read -e -p "Enter を押して続行します..." done } -# タスクリストを表示します +# タスクリストを表示 list_tasks() { - echo "保存された同期タスク:" + echo "保存された同期タスク:" echo "---------------------------------" awk -F'|' '{print NR " - " $1 " ( " $2 " -> " $3":"$4 " )"}' "$CONFIG_FILE" echo "---------------------------------" } -# 新しいタスクを追加します +# 新しいタスクを追加する add_task() { - send_stats "新しい同期タスクを追加します" - echo "新しい同期タスクを作成する例:" - echo "- タスク名:backup_www" - echo "- ローカルディレクトリ: /var /www" - echo "- リモートアドレス:user@192.168.1.100" - echo "- リモートディレクトリ: /バックアップ /www" - echo "- ポート番号(デフォルト22)" + send_stats "新しい同期タスクを追加する" + echo "新しい同期タスクの作成例:" + echo "- タスク名:backup_www" + echo "- ローカルディレクトリ: /var/www" + echo "- リモートアドレス: user@192.168.1.100" + echo "- リモートディレクトリ: /backup/www" + echo "- ポート番号 (デフォルトは 22)" echo "---------------------------------" - read -e -p "タスク名を入力してください:" name - read -e -p "ローカルディレクトリを入力してください:" local_path - read -e -p "リモートディレクトリを入力してください:" remote_path - read -e -p "リモートユーザー@IPを入力してください:" remote - read -e -p "SSHポートを入力してください(デフォルト22):" port + read -e -p "タスク名を入力してください:" name + read -e -p "ローカル ディレクトリを入力してください:" local_path + read -e -p "リモート ディレクトリを入力してください:" remote_path + read -e -p "リモート ユーザー@IP を入力してください:" remote + read -e -p "SSH ポートを入力してください (デフォルトは 22):" port port=${port:-22} - echo "認証方法を選択してください:" - echo "1。パスワード" - echo "2。キー" - read -e -p "(1/2)を選択してください:" auth_choice + echo "認証方法を選択してください:" + echo "1. パスワード" + echo "2. キー" + read -e -p "(1/2) を選択してください:" auth_choice case $auth_choice in 1) - read -s -p "パスワードを入力してください:" password_or_key + read -s -p "パスワードを入力してください:" password_or_key echo # 换行 auth_method="password" ;; 2) - echo "キーコンテンツを貼り付けてください(貼り付け後に2回Enterを押します)を押してください):" + echo "キーの内容を貼り付けてください (貼り付け後に Enter を 2 回押します)。" local password_or_key="" while IFS= read -r line; do - # 入力が空で、キーコンテンツにすでに開始が含まれている場合、入力は終了します + # 入力が空行で、キーの内容にすでに先頭が含まれている場合は、入力を終了します if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # それが最初の行であるか、キーコンテンツが入力されている場合は、さらに追加し続けます + # それが最初の行である場合、またはすでにキーコンテンツの入力を開始している場合は、追加を続けます。 if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then password_or_key+="${line}"$'\n' fi done - # キーコンテンツのかどうかを確認してください + # キーコンテンツかどうかを確認する if [[ "$password_or_key" == *"-----BEGIN"* && "$password_or_key" == *"PRIVATE KEY-----"* ]]; then local key_file="$KEY_DIR/${name}_sync.key" echo -n "$password_or_key" > "$key_file" @@ -6162,63 +6609,63 @@ add_task() { password_or_key="$key_file" auth_method="key" else - echo "無効なキーコンテンツ!" + echo "キーの内容が無効です!" return fi ;; *) - echo "無効な選択!" + echo "無効な選択です!" return ;; esac - echo "同期モードを選択してください:" - echo "1。標準モード(-AVZ)" - echo "2。ターゲットファイル(-avz - delete)を削除します" - read -e -p "(1/2)を選択してください:" mode + echo "同期モードを選択してください:" + echo "1. 標準モード (-avz)" + echo "2. 対象ファイルを削除(-avz --delete)" + read -e -p "(1/2) を選択してください:" mode case $mode in 1) options="-avz" ;; 2) options="-avz --delete" ;; - *) echo "無効な選択、デフォルト-AVZを使用します"; options="-avz" ;; + *) echo "選択が無効です。デフォルトの -avz を使用してください"; options="-avz" ;; esac echo "$name|$local_path|$remote|$remote_path|$port|$options|$auth_method|$password_or_key" >> "$CONFIG_FILE" install rsync rsync - echo "タスクが節約されました!" + echo "ミッションが保存されました!" } -# タスクを削除します +# タスクの削除 delete_task() { - send_stats "同期タスクを削除します" - read -e -p "削除するには、タスク番号を入力してください。" num + send_stats "同期タスクの削除" + read -e -p "削除するタスク番号を入力してください:" num local task=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$task" ]]; then - echo "エラー:対応するタスクは見つかりませんでした。" + echo "エラー: 対応するタスクが見つかりませんでした。" return fi IFS='|' read -r name local_path remote remote_path port options auth_method password_or_key <<< "$task" - # タスクがキーファイルを使用している場合、キーファイルを削除します + # タスクがキー ファイルを使用している場合は、キー ファイルを削除します if [[ "$auth_method" == "key" && "$password_or_key" == "$KEY_DIR"* ]]; then rm -f "$password_or_key" fi sed -i "${num}d" "$CONFIG_FILE" - echo "削除されたタスク!" + echo "タスクが削除されました!" } run_task() { - send_stats "同期タスクを実行します" + send_stats "同期タスクを実行する" CONFIG_FILE="$HOME/.rsync_tasks" CRON_FILE="$HOME/.rsync_cron" - # パラメーターを分析します + # パラメータを解析する local direction="push" # 默认是推送到远端 local num @@ -6229,51 +6676,51 @@ run_task() { num="$1" fi - # 着信タスク番号がない場合は、ユーザーに入力するように促します + # タスク番号が渡されない場合、ユーザーは入力を求められます。 if [[ -z "$num" ]]; then - read -e -p "実行するタスク番号を入力してください:" num + read -e -p "実行するタスク番号を入力してください:" num fi local task=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$task" ]]; then - echo "エラー:タスクは見つかりませんでした!" + echo "エラー: タスクが見つかりませんでした。" return fi IFS='|' read -r name local_path remote remote_path port options auth_method password_or_key <<< "$task" - # 同期の方向に従ってソースとターゲットのパスを調整します + # 同期方向に基づいてソースパスと宛先パスを調整する if [[ "$direction" == "pull" ]]; then - echo "同期をローカルに引く:$remote:$local_path -> $remote_path" + echo "ローカルへのプルと同期:$remote:$local_path -> $remote_path" source="$remote:$local_path" destination="$remote_path" else - echo "同期をリモートエンドに押します:$local_path -> $remote:$remote_path" + echo "リモートエンドへのプッシュと同期:$local_path -> $remote:$remote_path" source="$local_path" destination="$remote:$remote_path" fi - # SSH接続の共通パラメーターを追加します + # SSH接続の共通パラメータを追加する local ssh_options="-p $port -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" if [[ "$auth_method" == "password" ]]; then if ! command -v sshpass &> /dev/null; then - echo "エラー:SSHPassはインストールされていません。最初にSSHPassをインストールしてください。" - echo "インストール方法:" + echo "エラー: sshpass がインストールされていません。最初に sshpass をインストールしてください。" + echo "インストール方法:" echo " - Ubuntu/Debian: apt install sshpass" echo " - CentOS/RHEL: yum install sshpass" return fi sshpass -p "$password_or_key" rsync $options -e "ssh $ssh_options" "$source" "$destination" else - # キーファイルが存在するかどうか、およびアクセス許可が正しいかどうかを確認します + # キーファイルが存在するかどうか、および権限が正しいかどうかを確認してください if [[ ! -f "$password_or_key" ]]; then - echo "エラー:キーファイルが存在しません:$password_or_key" + echo "エラー: キー ファイルが存在しません:$password_or_key" return fi if [[ "$(stat -c %a "$password_or_key")" != "600" ]]; then - echo "警告:キーファイルのアクセス許可が正しくなく、修理されています..." + echo "警告: キー ファイルのアクセス許可が正しくありません。修正中です..." chmod 600 "$password_or_key" fi @@ -6281,32 +6728,32 @@ run_task() { fi if [[ $? -eq 0 ]]; then - echo "同期は完了です!" + echo "同期が完了しました!" else - echo "同期は失敗しました!以下を確認してください。" - echo "1。ネットワーク接続は正常ですか?" - echo "2。リモートホストにアクセスできますか?" - echo "3。認証情報は正しいですか?" - echo "4.ローカルおよびリモートディレクトリには正しいアクセス許可がありますか" + echo "同期に失敗しました!以下の点をご確認ください。" + echo "1. ネットワーク接続は正常ですか?" + echo "2. リモートホストにアクセスできるかどうか" + echo "3. 認証情報は正しいですか?" + echo "4. ローカル ディレクトリとリモート ディレクトリには正しいアクセス許可がありますか?" fi } -# 時限タスクを作成します +# スケジュールされたタスクを作成する schedule_task() { - send_stats "同期タイミングタスクを追加します" + send_stats "同期のスケジュールされたタスクを追加する" - read -e -p "定期的に同期するには、タスク番号を入力してください。" num + read -e -p "定期的に同期するタスク番号を入力してください:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then - echo "エラー:有効なタスク番号を入力してください!" + echo "エラー: 有効なタスク番号を入力してください。" return fi - echo "時限実行間隔を選択してください:" - echo "1)1時間に1回実行します" - echo "2)1日1回実行します" - echo "3)週に1回実行します" - read -e -p "オプションを入力してください(1/2/3):" interval + echo "スケジュールされた実行間隔を選択してください:" + echo "1) 1時間に1回実行" + echo "2) 1日1回実行" + echo "3) 週に1回実行" + read -e -p "オプションを入力してください (1/2/3):" interval local random_minute=$(shuf -i 0-59 -n 1) # 生成 0-59 之间的随机分钟数 local cron_time="" @@ -6314,42 +6761,42 @@ schedule_task() { 1) cron_time="$random_minute * * * *" ;; # 每小时,随机分钟执行 2) cron_time="$random_minute 0 * * *" ;; # 每天,随机分钟执行 3) cron_time="$random_minute 0 * * 1" ;; # 每周,随机分钟执行 - *) echo "エラー:有効なオプションを入力してください!" ; return ;; + *) echo "エラー: 有効なオプションを入力してください。" ; return ;; esac local cron_job="$cron_time k rsync_run $num" local cron_job="$cron_time k rsync_run $num" - # 同じタスクが既に存在するかどうかを確認してください + # 同じタスクがすでに存在するかどうかを確認する if crontab -l | grep -q "k rsync_run $num"; then - echo "エラー:このタスクのタイミング同期はすでに存在しています!" + echo "エラー: このタスクのスケジュールされた同期はすでに存在します。" return fi - # ユーザーにクロンタブを作成します + # ユーザーのcrontabに作成 (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "タイミングタスクが作成されました。$cron_job" + echo "スケジュールされたタスクが作成されました:$cron_job" } -# スケジュールされたタスクを表示します +# スケジュールされたタスクを表示する view_tasks() { - echo "現在のタイミングタスク:" + echo "現在スケジュールされているタスク:" echo "---------------------------------" crontab -l | grep "k rsync_run" echo "---------------------------------" } -# タイミングタスクを削除します +# スケジュールされたタスクを削除する delete_task_schedule() { - send_stats "同期タイミングタスクを削除します" - read -e -p "削除するには、タスク番号を入力してください。" num + send_stats "同期のスケジュールされたタスクを削除する" + read -e -p "削除するタスク番号を入力してください:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then - echo "エラー:有効なタスク番号を入力してください!" + echo "エラー: 有効なタスク番号を入力してください。" return fi crontab -l | grep -v "k rsync_run $num" | crontab - - echo "削除されたタスク番号$numタイミングタスク" + echo "タスク番号が削除されました$numスケジュールされたタスク" } @@ -6360,20 +6807,20 @@ rsync_manager() { while true; do clear - echo "RSYNCリモート同期ツール" - echo "リモートディレクトリ間の同期は、増分同期、効率的、安定性をサポートします。" + echo "Rsync リモート同期ツール" + echo "リモート ディレクトリ間の同期は、効率的で安定した増分同期をサポートしています。" echo "---------------------------------" list_tasks echo view_tasks echo - echo "1.新しいタスクを作成します2。タスクを削除します" - echo "3.リモートエンドにローカル同期を実行する4。ローカルエンドにリモート同期を実行する" - echo "5.タイミングタスクを作成6。タイミングタスクを削除します" + echo "1. 新しいタスクを作成します。 2. タスクを削除します。" + echo "3. リモート サイトへのローカル同期を実行します。 4. ローカル サイトへのリモート同期を実行します。" + echo "5. スケジュールされたタスクを作成します。 6. スケジュールされたタスクを削除します。" echo "---------------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "---------------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case $choice in 1) add_task ;; 2) delete_task ;; @@ -6382,9 +6829,9 @@ rsync_manager() { 5) schedule_task ;; 6) delete_task_schedule ;; 0) break ;; - *) echo "無効な選択、もう一度やり直してください。" ;; + *) echo "選択が無効です。もう一度お試しください。" ;; esac - read -e -p "Enterを押して続行します..." + read -e -p "Enter を押して続行します..." done } @@ -6396,10 +6843,10 @@ rsync_manager() { -linux_ps() { +linux_info() { clear - send_stats "システム情報クエリ" + send_stats "システム情報の問い合わせ" ip_address @@ -6443,47 +6890,51 @@ linux_ps() { local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1 % 3600) / 60); if (run_days > 0) printf("%d天 ", run_days); if (run_hours > 0) printf("%d时 ", run_hours); printf("%d分\n", run_minutes)}') + local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1% 3600) / 60); if (run_days > 0) printf("%d day ", run_days); if (実行時間 > 0) printf("%d 時間 ", 実行時間); printf("%d 分\n", run_ minutes)}') local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" - echo -e "システム情報クエリ" + echo -e "システム情報の問い合わせ" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}ホスト名:${gl_bai}$hostname" - echo -e "${gl_kjlan}システムバージョン:${gl_bai}$os_info" - echo -e "${gl_kjlan}Linuxバージョン:${gl_bai}$kernel_version" + echo -e "${gl_kjlan}ホスト名:${gl_bai}$hostname" + echo -e "${gl_kjlan}システムバージョン:${gl_bai}$os_info" + echo -e "${gl_kjlan}Linux バージョン:${gl_bai}$kernel_version" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPUアーキテクチャ:${gl_bai}$cpu_arch" - echo -e "${gl_kjlan}CPUモデル:${gl_bai}$cpu_info" - echo -e "${gl_kjlan}CPUコアの数:${gl_bai}$cpu_cores" - echo -e "${gl_kjlan}CPU頻度:${gl_bai}$cpu_freq" + echo -e "${gl_kjlan}CPU アーキテクチャ:${gl_bai}$cpu_arch" + echo -e "${gl_kjlan}CPUモデル:${gl_bai}$cpu_info" + echo -e "${gl_kjlan}CPUコアの数:${gl_bai}$cpu_cores" + echo -e "${gl_kjlan}CPU周波数:${gl_bai}$cpu_freq" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU占有:${gl_bai}$cpu_usage_percent%" - echo -e "${gl_kjlan}システムの負荷:${gl_bai}$load" - echo -e "${gl_kjlan}物理的記憶:${gl_bai}$mem_info" - echo -e "${gl_kjlan}仮想メモリ:${gl_bai}$swap_info" - echo -e "${gl_kjlan}ハードディスクの職業:${gl_bai}$disk_info" + echo -e "${gl_kjlan}CPU使用率:${gl_bai}$cpu_usage_percent%" + echo -e "${gl_kjlan}システム負荷:${gl_bai}$load" + echo -e "${gl_kjlan}TCP|UDP 接続の数:${gl_bai}$tcp_count|$udp_count" + echo -e "${gl_kjlan}物理メモリ:${gl_bai}$mem_info" + echo -e "${gl_kjlan}仮想メモリ:${gl_bai}$swap_info" + echo -e "${gl_kjlan}ハードドライブの使用状況:${gl_bai}$disk_info" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}合計受信:${gl_bai}$rx" - echo -e "${gl_kjlan}合計送信:${gl_bai}$tx" + echo -e "${gl_kjlan}受け取った合計:${gl_bai}$rx" + echo -e "${gl_kjlan}送信合計:${gl_bai}$tx" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}ネットワークアルゴリズム:${gl_bai}$congestion_algorithm $queue_algorithm" + echo -e "${gl_kjlan}ネットワークアルゴリズム:${gl_bai}$congestion_algorithm $queue_algorithm" echo -e "${gl_kjlan}-------------" echo -e "${gl_kjlan}オペレーター:${gl_bai}$isp_info" if [ -n "$ipv4_address" ]; then - echo -e "${gl_kjlan}IPv4アドレス:${gl_bai}$ipv4_address" + echo -e "${gl_kjlan}IPv4アドレス:${gl_bai}$ipv4_address" fi if [ -n "$ipv6_address" ]; then - echo -e "${gl_kjlan}IPv6アドレス:${gl_bai}$ipv6_address" + echo -e "${gl_kjlan}IPv6アドレス:${gl_bai}$ipv6_address" fi - echo -e "${gl_kjlan}DNSアドレス:${gl_bai}$dns_addresses" - echo -e "${gl_kjlan}地理的場所:${gl_bai}$country $city" - echo -e "${gl_kjlan}システム時間:${gl_bai}$timezone $current_time" + echo -e "${gl_kjlan}DNS アドレス:${gl_bai}$dns_addresses" + echo -e "${gl_kjlan}位置:${gl_bai}$country $city" + echo -e "${gl_kjlan}システム時間:${gl_bai}$timezone $current_time" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}ランタイム:${gl_bai}$runtime" + echo -e "${gl_kjlan}実行時間:${gl_bai}$runtime" echo @@ -6496,111 +6947,111 @@ linux_tools() { while true; do clear - # send_stats「基本ツール」 + # send_stats "基本ツール" echo -e "基本的なツール" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}カールダウンロードツール${gl_huang}★${gl_bai} ${gl_kjlan}2. ${gl_bai}WGETダウンロードツール${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}3. ${gl_bai}SUDOスーパー管理許可ツール${gl_kjlan}4. ${gl_bai}Socat Communication Connection Tool" - echo -e "${gl_kjlan}5. ${gl_bai}HTOPシステム監視ツール${gl_kjlan}6. ${gl_bai}IFTOPネットワークトラフィック監視ツール" - echo -e "${gl_kjlan}7. ${gl_bai}ジップzip圧縮減圧ツールを解凍します${gl_kjlan}8. ${gl_bai}TAR GZ圧縮減圧ツール" - echo -e "${gl_kjlan}9. ${gl_bai}TMUXマルチチャネルバックグラウンドランニングツール${gl_kjlan}10. ${gl_bai}Live StreamingツールをエンコードするFFMPEGビデオ" + echo -e "${gl_kjlan}1. ${gl_bai}カールダウンロードツール${gl_huang}★${gl_bai} ${gl_kjlan}2. ${gl_bai}wgetダウンロードツール${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}3. ${gl_bai}sudo スーパー管理者特権ツール${gl_kjlan}4. ${gl_bai}socat通信接続ツール" + echo -e "${gl_kjlan}5. ${gl_bai}htop システム監視ツール${gl_kjlan}6. ${gl_bai}iftop ネットワークトラフィック監視ツール" + echo -e "${gl_kjlan}7. ${gl_bai}unzip ZIP圧縮・解凍ツール${gl_kjlan}8. ${gl_bai}tar GZ 圧縮および解凍ツール" + echo -e "${gl_kjlan}9. ${gl_bai}tmux マルチチャネル バックグラウンド実行ツール${gl_kjlan}10. ${gl_bai}ffmpeg ビデオエンコードライブストリーミングツール" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}BTOPモダン監視ツール${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}範囲ファイル管理ツール" - echo -e "${gl_kjlan}13. ${gl_bai}NCDUディスク職業視聴ツール${gl_kjlan}14. ${gl_bai}FZFグローバル検索ツール" - echo -e "${gl_kjlan}15. ${gl_bai}VIMテキストエディター${gl_kjlan}16. ${gl_bai}ナノテキストエディター${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}gitバージョン制御システム" + echo -e "${gl_kjlan}11. ${gl_bai}btop 最新の監視ツール${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}レンジャーファイル管理ツール" + echo -e "${gl_kjlan}13. ${gl_bai}ncdu ディスク使用量表示ツール${gl_kjlan}14. ${gl_bai}fzf グローバル検索ツール" + echo -e "${gl_kjlan}15. ${gl_bai}vim テキストエディタ${gl_kjlan}16. ${gl_bai}ナノテキストエディタ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}17. ${gl_bai}git バージョン管理システム${gl_kjlan}18. ${gl_bai}opencode AI プログラミング アシスタント${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}マトリックス画面保証${gl_kjlan}22. ${gl_bai}列車のスクリーンのセキュリティ" - echo -e "${gl_kjlan}26. ${gl_bai}テトリスゲーム${gl_kjlan}27. ${gl_bai}ヘビを食べるゲーム" - echo -e "${gl_kjlan}28. ${gl_bai}スペースインベーダーゲーム" + echo -e "${gl_kjlan}21. ${gl_bai}マトリックス スクリーンセーバー${gl_kjlan}22. ${gl_bai}走る電車のスクリーンセーバー" + echo -e "${gl_kjlan}26. ${gl_bai}テトリスのミニゲーム${gl_kjlan}27. ${gl_bai}ヘビのミニゲーム" + echo -e "${gl_kjlan}28. ${gl_bai}スペースインベーダーのミニゲーム" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}すべてをインストールします${gl_kjlan}32. ${gl_bai}すべてのインストール(スクリーンセーバーとゲームを除く)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}すべてをアンインストールします" + echo -e "${gl_kjlan}31. ${gl_bai}すべてインストールする${gl_kjlan}32. ${gl_bai}すべてインストール (スクリーンセーバーとゲームを除く)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}すべてアンインストールする" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}指定されたツールをインストールします${gl_kjlan}42. ${gl_bai}指定されたツールをアンインストールします" + echo -e "${gl_kjlan}41. ${gl_bai}指定されたツールをインストールする${gl_kjlan}42. ${gl_bai}指定されたツールをアンインストールします" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) clear install curl clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" curl --help - send_stats "カールをインストールします" + send_stats "カールをインストールする" ;; 2) clear install wget clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" wget --help - send_stats "WGETをインストールします" + send_stats "wgetをインストールする" ;; 3) clear install sudo clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" sudo --help - send_stats "sudoをインストールします" + send_stats "sudoをインストールする" ;; 4) clear install socat clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" socat -h - send_stats "SOCATをインストールします" + send_stats "socatをインストールする" ;; 5) clear install htop clear htop - send_stats "HTOPをインストールします" + send_stats "htopをインストールする" ;; 6) clear install iftop clear iftop - send_stats "IFTOPをインストールします" + send_stats "iftop をインストールする" ;; 7) clear install unzip clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" unzip - send_stats "unzipをインストールします" + send_stats "インストール解凍" ;; 8) clear install tar clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" tar --help - send_stats "タールをインストールします" + send_stats "tarをインストールする" ;; 9) clear install tmux clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" tmux --help - send_stats "tmuxをインストールします" + send_stats "tmuxをインストールする" ;; 10) clear install ffmpeg clear - echo "ツールがインストールされており、使用方法は次のとおりです。" + echo "ツールはインストールされており、次のように使用されます。" ffmpeg --help - send_stats "ffmpegをインストールします" + send_stats "ffmpegをインストールする" ;; 11) @@ -6608,7 +7059,7 @@ linux_tools() { install btop clear btop - send_stats "BTOPをインストールします" + send_stats "btopをインストールする" ;; 12) clear @@ -6617,7 +7068,7 @@ linux_tools() { clear ranger cd ~ - send_stats "レンジャーをインストールします" + send_stats "レンジャーをインストールする" ;; 13) clear @@ -6626,7 +7077,7 @@ linux_tools() { clear ncdu cd ~ - send_stats "NCDUをインストールします" + send_stats "ncdu をインストールする" ;; 14) clear @@ -6635,7 +7086,7 @@ linux_tools() { clear fzf cd ~ - send_stats "FZFをインストールします" + send_stats "fzfをインストールする" ;; 15) clear @@ -6644,7 +7095,7 @@ linux_tools() { clear vim -h cd ~ - send_stats "VIMをインストールします" + send_stats "vimをインストールする" ;; 16) clear @@ -6653,7 +7104,7 @@ linux_tools() { clear nano -h cd ~ - send_stats "ナノをインストールします" + send_stats "ナノをインストールする" ;; @@ -6664,75 +7115,89 @@ linux_tools() { clear git --help cd ~ - send_stats "gitをインストールします" + send_stats "gitをインストールする" + ;; + + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "オープンコードをインストールする" ;; + 21) clear install cmatrix clear cmatrix - send_stats "cmatrixをインストールします" + send_stats "cmatrix をインストールする" ;; 22) clear install sl clear sl - send_stats "SLをインストールします" + send_stats "SLをインストールする" ;; 26) clear install bastet clear bastet - send_stats "バステットをインストールします" + send_stats "バステトをインストールする" ;; 27) clear install nsnake clear nsnake - send_stats "nsnakeをインストールします" + send_stats "nsnakeをインストールする" ;; + 28) clear install ninvaders clear ninvaders - send_stats "Ninvadersをインストールします" + send_stats "ニンベーダーをインストールする" ;; 31) clear - send_stats "すべてをインストールします" + send_stats "すべてインストールする" install curl wget sudo socat htop iftop unzip tar tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git ;; 32) clear - send_stats "すべてをインストールします(ゲームやスクリーンセーバーを除く)" + send_stats "すべてインストール (ゲームとスクリーンセーバーを除く)" install curl wget sudo socat htop iftop unzip tar tmux ffmpeg btop ranger ncdu fzf vim nano git ;; 33) clear - send_stats "すべてをアンインストールします" + send_stats "すべてアンインストールする" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) clear - read -e -p "インストールされているツール名(Wget Curl Sudo htop)を入力してください。" installname + read -e -p "インストールされているツール名 (wgetcurlsudohtop) を入力してください:" installname install $installname - send_stats "指定されたソフトウェアをインストールします" + send_stats "指定されたソフトウェアをインストールする" ;; 42) clear - read -e -p "アンインストールされていないツール名(HTOP UFW TMUX CMATRIX)を入力してください。" removename + read -e -p "アンインストールされたツール名 (htop ufw tmux cmatrix) を入力してください:" removename remove $removename - send_stats "指定されたソフトウェアをアンインストールします" + send_stats "指定したソフトウェアをアンインストールする" ;; 0) @@ -6740,7 +7205,7 @@ linux_tools() { ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -6760,24 +7225,24 @@ linux_bbr() { clear local congestion_algorithm=$(sysctl -n net.ipv4.tcp_congestion_control) local queue_algorithm=$(sysctl -n net.core.default_qdisc) - echo "現在のTCPブロッキングアルゴリズム:$congestion_algorithm $queue_algorithm" + echo "現在の TCP ブロック アルゴリズム:$congestion_algorithm $queue_algorithm" echo "" echo "BBR管理" echo "------------------------" - echo "1。BBRV3 2をオンにします。BBRV3(再起動)をオフにします" + echo "1. BBRv3 をオンにする 2. BBRv3 をオフにする (再起動します)" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) bbr_on - send_stats "AlpineはBBR3を有効にします" + send_stats "アルパインがBBR3をオープン" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6801,77 +7266,405 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # send_stats「Docker Management」 - echo -e "Docker管理" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Docker環境をインストールして更新します${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}Dockerグローバルステータスを表示します${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}Dockerコンテナ管理${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}Docker画像管理" - echo -e "${gl_kjlan}5. ${gl_bai}Dockerネットワーク管理" - echo -e "${gl_kjlan}6. ${gl_bai}Dockerボリューム管理" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}7. ${gl_bai}清潔な役に立たないドッカーコンテナとミラーネットワークデータボリューム" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}8. ${gl_bai}Dockerソースを交換します" - echo -e "${gl_kjlan}9. ${gl_bai}daemon.jsonファイルを編集します" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}docker-ipv6アクセスを有効にします" - echo -e "${gl_kjlan}12. ${gl_bai}docker-ipv6アクセスを閉じます" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}20. ${gl_bai}Docker環境をアンインストールします" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' - case $sub_choice in - 1) - clear - send_stats "Docker環境をインストールします" - install_add_docker + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } - ;; - 2) - clear - local container_count=$(docker ps -a -q 2>/dev/null | wc -l) - local image_count=$(docker images -q 2>/dev/null | wc -l) - local network_count=$(docker network ls -q 2>/dev/null | wc -l) - local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}現在のバックアップ リスト:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "バックアップなし" + } - send_stats "Dockerグローバルステータス" - echo "Dockerバージョン" - docker -v - docker compose version - echo "" - echo -e "Docker画像:${gl_lv}$image_count${gl_bai} " - docker image ls - echo "" - echo -e "Dockerコンテナ:${gl_lv}$container_count${gl_bai}" - docker ps -a - echo "" - echo -e "Dockerボリューム:${gl_lv}$volume_count${gl_bai}" - docker volume ls - echo "" - echo -e "Dockerネットワーク:${gl_lv}$network_count${gl_bai}" - docker network ls - echo "" + # ---------------------------- + # バックアップ + # ---------------------------- + backup_docker() { + send_stats "Dockerバックアップ" + + echo -e "${YELLOW}Docker コンテナをバックアップしています...${NC}" + docker ps --format '{{.Names}}' + read -e -p "バックアップするコンテナの名前を入力してください (実行中のすべてのコンテナをバックアップするには、複数のスペースを区切って Enter キーを押します)。" containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}コンテナが見つかりません${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# 自動生成された復元スクリプト" >> "$RESTORE_SCRIPT" + + # パッケージ化の繰り返しを避けるために、パッケージ化された Compose プロジェクトのパスを記録します。 + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}バックアップコンテナ:$c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}検出されました$cdocker-composeコンテナです${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "作成ディレクトリが検出されません。パスを手動で入力してください。" project_dir + fi + + # Compose プロジェクトがすでにパッケージ化されている場合は、スキップしてください + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}プロジェクトの作成 [$project_name] すでにバックアップされているので、繰り返しのパッケージ化をスキップします...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose 復元:$project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}プロジェクトの作成 [$project_name] パッケージ内容:${project_dir}${NC}" + else + echo -e "${RED}docker-compose.yml が見つからないため、このコンテナをスキップします...${NC}" + fi + else + # 通常のコンテナバックアップボリューム + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "梱包量:$path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # ポート + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # 環境変数 + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # ボリュームマッピング + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # 鏡 + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# コンテナを復元:$c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # /home/docker 下のすべてのファイルをバックアップします (サブディレクトリを除く)。 + if [ -d "/home/docker" ]; then + echo -e "${BLUE}/home/docker 下のファイルをバックアップします...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}/home/docker 下のファイルは次のようにパッケージ化されています。${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}バックアップが完了しました:${BACKUP_DIR}${NC}" + echo -e "${GREEN}利用可能な復元スクリプト:${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # 削減 + # ---------------------------- + restore_docker() { + + send_stats "Docker の復元" + read -e -p "復元するバックアップ ディレクトリを入力してください:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}バックアップディレクトリが存在しません${NC}"; return; } + + echo -e "${BLUE}復元操作を開始しています...${NC}" + + install tar jq gzip + install_docker + + # --------- Compose プロジェクトの復元を優先します --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "元のパスが見つかりません。復元ディレクトリのパスを入力してください:" original_path + + # 作成プロジェクトのコンテナがすでに実行されているかどうかを確認します + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}プロジェクトの作成 [$project_name] コンテナはすでに実行されているため、復元をスキップします...${NC}" + continue + fi + + read -e -p "Compose プロジェクトの復元を確認します [$project_name] からパス [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "新しい復元パスを入力してください:" original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}プロジェクトの作成 [$project_name] は次のように抽出されました。$original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}プロジェクトの作成 [$project_name】レストア完了!${NC}" + fi + done + + # --------- 通常のコンテナの復元を続行 --------- + echo -e "${BLUE}通常の Docker コンテナを確認して復元します...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}処理容器:$container${NC}" + + # コンテナがすでに存在し、実行されているかどうかを確認します + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] すでに実行中のため、復元をスキップしています...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}ミラー情報が見つかりません。スキップしてください:$container${NC}"; continue; } + + # ポートマッピング + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # 環境変数 + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # ボリュームマッピング + ボリュームデータリカバリ + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "ボリュームデータを復元します。$VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # 既存だが実行されていないコンテナを削除する + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] は存在しますが実行されていない場合は、古いコンテナを削除してください...${NC}" + docker rm -f "$container" + fi + + # コンテナの起動 + echo "復元コマンドを実行します: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}共通コンテナのバックアップ情報が見つかりません${NC}" + + # /home/docker 下のファイルを復元する + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}/home/docker の下にファイルを復元しています...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}/home/docker 下のファイルが復元されました${NC}" + else + echo -e "${YELLOW}/home/docker の下にあるファイルのバックアップが見つかりませんでした。スキップしています...${NC}" + fi + + + } + + + # ---------------------------- + # 移行する + # ---------------------------- + migrate_docker() { + send_stats "Docker の移行" + install jq + read -e -p "移行するバックアップ ディレクトリを入力してください:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}バックアップディレクトリが存在しません${NC}"; return; } + + read -e -p "ターゲットサーバーIP:" TARGET_IP + read -e -p "ターゲットサーバーの SSH ユーザー名:" TARGET_USER + read -e -p "ターゲットサーバーの SSH ポート [デフォルト 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}バックアップを転送中...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # キーを使用してログインする + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # バックアップの削除 + # ---------------------------- + delete_backup() { + send_stats "Dockerバックアップファイルの削除" + read -e -p "削除するバックアップ ディレクトリを入力してください:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}バックアップディレクトリが存在しません${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}削除されたバックアップ:${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # メインメニュー + # ---------------------------- + main_menu() { + send_stats "Docker バックアップ 移行 復元" + while true; do + clear + echo "------------------------" + echo -e "Docker バックアップ/移行/復元ツール" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. Docker プロジェクトをバックアップする" + echo -e "2. Docker プロジェクトを移行する" + echo -e "3. Docker プロジェクトを復元する" + echo -e "4. Dockerプロジェクトのバックアップファイルを削除する" + echo "------------------------" + echo -e "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択してください:" choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}無効なオプション${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "ドッカー管理" + echo -e "Docker管理" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}Docker環境のインストールと更新${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}Docker のグローバル ステータスを表示する${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}Dockerコンテナ管理${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}Dockerイメージ管理" + echo -e "${gl_kjlan}5. ${gl_bai}Dockerネットワーク管理" + echo -e "${gl_kjlan}6. ${gl_bai}Docker ボリューム管理" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}7. ${gl_bai}不要な Docker コンテナをクリーンアップし、ネットワーク データ ボリュームをミラーリングします" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}8. ${gl_bai}Dockerソースを変更する" + echo -e "${gl_kjlan}9. ${gl_bai}daemon.json ファイルを編集する" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}11. ${gl_bai}Docker-ipv6 アクセスを有効にする" + echo -e "${gl_kjlan}12. ${gl_bai}Docker-ipv6 アクセスをオフにする" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}Docker環境のバックアップ/移行/復元" + echo -e "${gl_kjlan}20. ${gl_bai}Docker環境をアンインストールする" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "選択肢を入力してください:" sub_choice + + case $sub_choice in + 1) + clear + send_stats "Docker環境をインストールする" + install_add_docker + + ;; + 2) + clear + local container_count=$(docker ps -a -q 2>/dev/null | wc -l) + local image_count=$(docker images -q 2>/dev/null | wc -l) + local network_count=$(docker network ls -q 2>/dev/null | wc -l) + local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + + send_stats "ドッカーのグローバルステータス" + echo "Docker のバージョン" + docker -v + docker compose version + + echo "" + echo -e "Docker イメージ:${gl_lv}$image_count${gl_bai} " + docker image ls + echo "" + echo -e "Docker コンテナ:${gl_lv}$container_count${gl_bai}" + docker ps -a + echo "" + echo -e "Docker ボリューム:${gl_lv}$volume_count${gl_bai}" + docker volume ls + echo "" + echo -e "Docker ネットワーク:${gl_lv}$network_count${gl_bai}" + docker network ls + echo "" + + ;; + 3) + docker_ps + ;; + 4) + docker_image ;; - 3) - docker_ps - ;; - 4) - docker_image - ;; 5) while true; do @@ -6884,7 +7677,7 @@ linux_docker() { echo "------------------------------------------------------------" container_ids=$(docker ps -q) - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "コンテナ名" "ネットワーク名" "IPアドレス" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") @@ -6901,36 +7694,36 @@ linux_docker() { done echo "" - echo "ネットワーク操作" + echo "ネットワーク運用" echo "------------------------" - echo "1.ネットワークを作成します" - echo "2。インターネットに参加してください" - echo "3。ネットワークを終了します" - echo "4.ネットワークを削除します" + echo "1. ネットワークを作成する" + echo "2. ネットワークに参加する" + echo "3. ネットワークを終了します" + echo "4. ネットワークの削除" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "ネットワークを作成します" - read -e -p "新しいネットワーク名を設定します:" dockernetwork + send_stats "ネットワークの作成" + read -e -p "新しいネットワーク名を設定します。" dockernetwork docker network create $dockernetwork ;; 2) - send_stats "インターネットに参加してください" - read -e -p "ネットワーク名に参加してください:" dockernetwork - read -e -p "これらのコンテナはネットワークに追加されます(複数のコンテナ名はスペースで区切られています):" dockernames + send_stats "ネットワークに参加する" + read -e -p "ネットワーク名を追加します:" dockernetwork + read -e -p "どのコンテナがネットワークに参加しますか (複数のコンテナ名はスペースで区切ってください):" dockernames for dockername in $dockernames; do docker network connect $dockernetwork $dockername done ;; 3) - send_stats "インターネットに参加してください" - read -e -p "出口ネットワーク名:" dockernetwork - read -e -p "これらのコンテナはネットワークを終了します(複数のコンテナ名はスペースで区切られています):" dockernames + send_stats "ネットワークに参加する" + read -e -p "出口ネットワーク名:" dockernetwork + read -e -p "これらのコンテナはネットワークから終了します (複数のコンテナ名はスペースで区切ってください)。" dockernames for dockername in $dockernames; do docker network disconnect $dockernetwork $dockername @@ -6939,8 +7732,8 @@ linux_docker() { ;; 4) - send_stats "ネットワークを削除します" - read -e -p "削除するには、ネットワーク名を入力してください。" dockernetwork + send_stats "ネットワークを削除する" + read -e -p "削除するネットワーク名を入力してください:" dockernetwork docker network rm $dockernetwork ;; @@ -6954,29 +7747,29 @@ linux_docker() { 6) while true; do clear - send_stats "Dockerボリューム管理" + send_stats "Docker ボリューム管理" echo "Dockerボリュームリスト" docker volume ls echo "" echo "ボリューム操作" echo "------------------------" - echo "1.新しいボリュームを作成します" - echo "2。指定されたボリュームを削除します" - echo "3.すべてのボリュームを削除します" + echo "1. 新しいボリュームを作成する" + echo "2. 指定したボリュームを削除します" + echo "3. すべてのボリュームを削除します" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - send_stats "新しいボリュームを作成します" - read -e -p "新しいボリューム名を設定します:" dockerjuan + send_stats "新しいボリュームを作成する" + read -e -p "新しいボリューム名を設定します。" dockerjuan docker volume create $dockerjuan ;; 2) - read -e -p "削除ボリューム名を入力します(スペースで複数のボリューム名を分離してください):" dockerjuans + read -e -p "削除ボリューム名を入力します (複数のボリューム名はスペースで区切ってください):" dockerjuans for dockerjuan in $dockerjuans; do docker volume rm $dockerjuan @@ -6985,7 +7778,7 @@ linux_docker() { ;; 3) - send_stats "すべてのボリュームを削除します" + send_stats "すべてのボリュームを削除する" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有未使用的卷吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -6994,7 +7787,7 @@ linux_docker() { [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -7007,7 +7800,7 @@ linux_docker() { ;; 7) clear - send_stats "Dockerクリーニング" + send_stats "Docker のクリーンアップ" read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}将清理无用的镜像容器网络,包括停止的容器,确定清理吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -7016,13 +7809,13 @@ linux_docker() { [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; 8) clear - send_stats "Dockerソース" + send_stats "Docker ソース" bash <(curl -sSL https://linuxmirrors.cn/docker.sh) ;; @@ -7033,21 +7826,29 @@ linux_docker() { restart docker ;; + + + 11) clear - send_stats "Docker V6が開いています" + send_stats "Docker v6 がオン" docker_ipv6_on ;; 12) clear - send_stats "Docker V6レベル" + send_stats "Docker v6 閉じる" docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear - send_stats "Dockerアンインストール" + send_stats "Docker のアンインストール" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定卸载docker环境吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -7059,7 +7860,7 @@ linux_docker() { [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -7068,7 +7869,7 @@ linux_docker() { kejilion ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -7085,140 +7886,141 @@ linux_test() { while true; do clear - # send_stats「テストスクリプトコレクション」 - echo -e "テストスクリプトコレクション" + # send_stats "テストスクリプト集" + echo -e "テストスクリプト集" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}IPおよびロック解除ステータス検出" - echo -e "${gl_kjlan}1. ${gl_bai}CHATGPTはステータス検出のロックを解除します" - echo -e "${gl_kjlan}2. ${gl_bai}リージョンストリーミングメディアのロック解除テスト" - echo -e "${gl_kjlan}3. ${gl_bai}YeahWUストリーミングメディアのロック解除検出" - echo -e "${gl_kjlan}4. ${gl_bai}XYKT IP品質の身体検査スクリプト${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}IPおよびロック解除ステータスの検出" + echo -e "${gl_kjlan}1. ${gl_bai}ChatGPTロック解除状態検出" + echo -e "${gl_kjlan}2. ${gl_bai}リージョンストリーミングメディアロック解除テスト" + echo -e "${gl_kjlan}3. ${gl_bai}Yeawu ストリーミング メディアのロック解除の検出" + echo -e "${gl_kjlan}4. ${gl_bai}xykt IP 品質チェック スクリプト${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}ネットワーク速度測定" - echo -e "${gl_kjlan}11. ${gl_bai}BestTrace 3ネットワークバックホール遅延ルーティングテスト" - echo -e "${gl_kjlan}12. ${gl_bai}MTR_TRACE 3ネットワークバックホールラインテスト" - echo -e "${gl_kjlan}13. ${gl_bai}SuperSpeed Three-Net速度測定" - echo -e "${gl_kjlan}14. ${gl_bai}nxtrace高速バックホールテストスクリプト" - echo -e "${gl_kjlan}15. ${gl_bai}Nxtraceは、IPバックホールテストスクリプトを指定します" - echo -e "${gl_kjlan}16. ${gl_bai}Ludashi2020 3ネットワークラインテスト" - echo -e "${gl_kjlan}17. ${gl_bai}I-ABC多機能速度テストスクリプト" - echo -e "${gl_kjlan}18. ${gl_bai}ネットワーク品質の高品質の身体検査スクリプト${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}ネットワーク回線速度テスト" + echo -e "${gl_kjlan}11. ${gl_bai}besttrace 3 ネットワーク バックホール遅延ルーティング テスト" + echo -e "${gl_kjlan}12. ${gl_bai}mtr_trace トリプルネットワークバックホール回線テスト" + echo -e "${gl_kjlan}13. ${gl_bai}超高速トリプルネットワーク速度テスト" + echo -e "${gl_kjlan}14. ${gl_bai}nxtrace 高速バックホール テスト スクリプト" + echo -e "${gl_kjlan}15. ${gl_bai}nxtrace は IP バックホール テスト スクリプトを指定します" + echo -e "${gl_kjlan}16. ${gl_bai}ludashi2020 3つのネットワーク回線テスト" + echo -e "${gl_kjlan}17. ${gl_bai}i-abc 多機能速度テスト スクリプト" + echo -e "${gl_kjlan}18. ${gl_bai}NetQuality ネットワーク品質チェック スクリプト${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}ハードウェアパフォーマンステスト" - echo -e "${gl_kjlan}21. ${gl_bai}YABSパフォーマンステスト" - echo -e "${gl_kjlan}22. ${gl_bai}IICU/GB5 CPUパフォーマンステストスクリプト" + echo -e "${gl_kjlan}21. ${gl_bai}yabsパフォーマンステスト" + echo -e "${gl_kjlan}22. ${gl_bai}icu/gb5 CPU パフォーマンステストスクリプト" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}包括的なテスト" + echo -e "${gl_kjlan}総合的なテスト" echo -e "${gl_kjlan}31. ${gl_bai}ベンチパフォーマンステスト" - echo -e "${gl_kjlan}32. ${gl_bai}SpiritySDX Fusion Monster Review${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}32. ${gl_bai}Spiritysdx融合モンスターの評価${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}ノードクオリティ融合モンスターの評価${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) clear - send_stats "CHATGPTはステータス検出のロックを解除します" + send_stats "ChatGPTロック解除状態検出" bash <(curl -Ls https://cdn.jsdelivr.net/gh/missuo/OpenAI-Checker/openai.sh) ;; 2) clear - send_stats "リージョンストリーミングメディアのロック解除テスト" + send_stats "リージョンストリーミングメディアロック解除テスト" bash <(curl -L -s check.unlock.media) ;; 3) clear - send_stats "YeahWUストリーミングメディアのロック解除検出" + send_stats "Yeawu ストリーミング メディアのロック解除の検出" install wget wget -qO- ${gh_proxy}github.com/yeahwu/check/raw/main/check.sh | bash ;; 4) clear - send_stats "XYKT_IP品質の身体検査スクリプト" + send_stats "xykt_IP 品質チェック スクリプト" bash <(curl -Ls IP.Check.Place) ;; 11) clear - send_stats "BestTrace 3ネットワークバックホール遅延ルーティングテスト" + send_stats "besttrace トリプル ネットワーク バックホール遅延ルーティング テスト" install wget wget -qO- git.io/besttrace | bash ;; 12) clear - send_stats "MTR_TRACE 3ネットワークリターンラインテスト" + send_stats "mtr_trace トリプルネットワークバックホール回線テスト" curl ${gh_proxy}raw.githubusercontent.com/zhucaidan/mtr_trace/main/mtr_trace.sh | bash ;; 13) clear - send_stats "SuperSpeed Three-Net速度測定" + send_stats "超高速トリプルネットワーク速度テスト" bash <(curl -Lso- https://git.io/superspeed_uxh) ;; 14) clear - send_stats "nxtrace高速バックホールテストスクリプト" + send_stats "nxtrace 高速バックホール テスト スクリプト" curl nxtrace.org/nt |bash nexttrace --fast-trace --tcp ;; 15) clear - send_stats "Nxtraceは、IPバックホールテストスクリプトを指定します" - echo "参照できるIPのリスト" + send_stats "nxtrace は IP バックホール テスト スクリプトを指定します" + echo "参照IPリスト" echo "------------------------" - echo "北京テレコム:219.141.136.12" - echo "北京ユニコム:202.106.50.1" - echo "北京モバイル:221.179.155.161" - echo "上海通信:202.96.209.133" - echo "上海ユニコム:210.22.97.1" - echo "上海モバイル:211.136.112.200" - echo "広州通信:58.60.188.222" - echo "広州ユニコム:210.21.196.6" - echo "広州モバイル:120.196.165.24" - echo "成都通信:61.139.2.69" - echo "成都ユニコム:119.6.6.6" - echo "成都モバイル:211.137.96.205" - echo "Hunan Telecom:36.111.200.100" - echo "Hunan Unicom:42.48.16.100" - echo "Hunan Mobile:39.134.254.6" + echo "北京電信: 219.141.136.12" + echo "北京ユニコム: 202.106.50.1" + echo "北京モバイル: 221.179.155.161" + echo "上海電信: 202.96.209.133" + echo "上海ユニコム: 210.22.97.1" + echo "上海モバイル: 211.136.112.200" + echo "広州電信: 58.60.188.222" + echo "広州チャイナユニコム: 210.21.196.6" + echo "広州モバイル: 120.196.165.24" + echo "成都電信: 61.139.2.69" + echo "成都チャイナユニコム: 119.6.6.6" + echo "成都携帯電話: 211.137.96.205" + echo "湖南電信: 36.111.200.100" + echo "湖南ユニコム: 42.48.16.100" + echo "湖南省モバイル: 39.134.254.6" echo "------------------------" - read -e -p "指定されたIPを入力してください:" testip + read -e -p "特定の IP を入力します。" testip curl nxtrace.org/nt |bash nexttrace $testip ;; 16) clear - send_stats "Ludashi2020 3ネットワークラインテスト" + send_stats "ludashi2020 3つのネットワーク回線テスト" curl ${gh_proxy}raw.githubusercontent.com/ludashi2020/backtrace/main/install.sh -sSf | sh ;; 17) clear - send_stats "I-ABC多機能速度テストスクリプト" + send_stats "i-abc 多機能速度テスト スクリプト" bash <(curl -sL ${gh_proxy}raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh) ;; 18) clear - send_stats "ネットワーク品質のテストスクリプト" + send_stats "ネットワーク品質テストスクリプト" bash <(curl -sL Net.Check.Place) ;; 21) clear - send_stats "YABSパフォーマンステスト" + send_stats "yabsパフォーマンステスト" check_swap curl -sL yabs.sh | bash -s -- -i -5 ;; 22) clear - send_stats "IICU/GB5 CPUパフォーマンステストスクリプト" + send_stats "icu/gb5 CPU パフォーマンステストスクリプト" check_swap bash <(curl -sL bash.icu/gb5) ;; @@ -7229,17 +8031,25 @@ linux_test() { curl -Lso- bench.sh | bash ;; 32) - send_stats "SpiritySDX Fusion Monster Review" + send_stats "Spiritysdx フュージョンモンスター レビュー" + clear + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "ノードクオリティ融合モンスターの評価" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -7255,66 +8065,66 @@ linux_Oracle() { while true; do clear - send_stats "Oracle Cloud Scriptコレクション" - echo -e "Oracle Cloud Scriptコレクション" + send_stats "Oracle Cloudスクリプト・コレクション" + echo -e "Oracle Cloudスクリプト・コレクション" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}アイドルマシンアクティブスクリプトをインストールします" - echo -e "${gl_kjlan}2. ${gl_bai}アイドルマシンアクティブスクリプトをアンインストールします" + echo -e "${gl_kjlan}1. ${gl_bai}アイドル状態のマシンのアクティブ スクリプトをインストールする" + echo -e "${gl_kjlan}2. ${gl_bai}アイドル状態のマシンからアクティブなスクリプトをアンインストールする" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}DDシステムスクリプトを再インストールします" - echo -e "${gl_kjlan}4. ${gl_bai}探偵r開始スクリプト" - echo -e "${gl_kjlan}5. ${gl_bai}ルートパスワードログインモードをオンにします" - echo -e "${gl_kjlan}6. ${gl_bai}IPv6回復ツール" + echo -e "${gl_kjlan}3. ${gl_bai}DD 再インストール システム スクリプト" + echo -e "${gl_kjlan}4. ${gl_bai}探偵R起動スクリプト" + echo -e "${gl_kjlan}5. ${gl_bai}ROOTパスワードログインモードを有効にする" + echo -e "${gl_kjlan}6. ${gl_bai}IPV6回復ツール" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) clear - echo "アクティブスクリプト:CPUが10-20%を占めるメモリは20%を占めています" - read -e -p "必ずインストールしますか? (y/n):" choice + echo "アクティブ スクリプト: CPU 使用率 10 ~ 20% メモリ使用率 20%" + read -e -p "インストールしてもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) install_docker - # デフォルト値を設定します + # デフォルト値を設定する local DEFAULT_CPU_CORE=1 local DEFAULT_CPU_UTIL="10-20" local DEFAULT_MEM_UTIL=20 local DEFAULT_SPEEDTEST_INTERVAL=120 - # ユーザーにCPUコアの数と占有率の数を入力するように促し、入力した場合はデフォルト値を使用します。 - read -e -p "CPUコアの数を入力してください[デフォルト:$DEFAULT_CPU_CORE]: " cpu_core + # CPU コアの数と占有率を入力するようユーザーに求めます。ユーザーが Enter キーを押すと、デフォルト値が使用されます。 + read -e -p "CPU コアの数を入力してください [デフォルト:$DEFAULT_CPU_CORE]: " cpu_core local cpu_core=${cpu_core:-$DEFAULT_CPU_CORE} - read -e -p "CPU使用率の範囲(たとえば、10-20)を入力してください[デフォルト:$DEFAULT_CPU_UTIL]: " cpu_util + read -e -p "CPU 使用率の範囲 (例: 10 ~ 20) を入力してください [デフォルト:$DEFAULT_CPU_UTIL]: " cpu_util local cpu_util=${cpu_util:-$DEFAULT_CPU_UTIL} - read -e -p "メモリの使用率を入力してください[デフォルト:$DEFAULT_MEM_UTIL]: " mem_util + read -e -p "メモリ使用率を入力してください [デフォルト:$DEFAULT_MEM_UTIL]: " mem_util local mem_util=${mem_util:-$DEFAULT_MEM_UTIL} - read -e -p "SpeedTest間隔時間(秒)を入力してください[デフォルト:$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval + read -e -p "Speedtest の間隔時間 (秒) を入力してください [デフォルト:$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} - # Dockerコンテナを実行します - docker run -itd --name=lookbusy --restart=always \ + # Dockerコンテナを実行する + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ -e MEM_UTIL="$mem_util" \ -e SPEEDTEST_INTERVAL="$speedtest_interval" \ fogforest/lookbusy - send_stats "Oracle Cloudインストールアクティブスクリプト" + send_stats "Oracle Cloudインストール・アクティブ・スクリプト" ;; [Nn]) ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -7322,20 +8132,20 @@ linux_Oracle() { clear docker rm -f lookbusy docker rmi fogforest/lookbusy - send_stats "Oracle Cloudはアクティブスクリプトをアンインストールします" + send_stats "Oracle Cloudアンインストール・アクティブ・スクリプト" ;; 3) clear - echo "システムを再インストールします" + echo "システムを再インストールする" echo "--------------------------------" - echo -e "${gl_hong}知らせ:${gl_bai}再インストールは接触を失う危険であり、心配している人はそれを注意して使用する必要があります。再インストールには15分かかると予想されます。事前にデータをバックアップしてください。" - read -e -p "必ず続行しますか? (y/n):" choice + echo -e "${gl_hong}知らせ:${gl_bai}再インストールすると接続が切れる可能性がありますので、不安な方はご注意ください。再インストールには 15 分程度かかることが予想されますので、事前にデータをバックアップしてください。" + read -e -p "続行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) while true; do - read -e -p "再インストールするシステムを選択してください:1。Debian12| 2。Ubuntu20.04:" sys_choice + read -e -p "再インストールするシステムを選択してください: 1. Debian12 | 2.Ubuntu20.04:" sys_choice case "$sys_choice" in 1) @@ -7347,12 +8157,12 @@ linux_Oracle() { break # 结束循环 ;; *) - echo "選択の無効な、再入力してください。" + echo "選択が無効です。再入力してください。" ;; esac done - read -e -p "再インストールされたパスワードを入力してください:" vpspasswd + read -e -p "再インストール後にパスワードを入力してください:" vpspasswd install wget bash <(wget --no-check-certificate -qO- "${gh_proxy}raw.githubusercontent.com/MoeClub/Note/master/InstallNET.sh") $xitong -v 64 -p $vpspasswd -port 22 send_stats "Oracle Cloud再インストールシステムスクリプト" @@ -7361,14 +8171,15 @@ linux_Oracle() { echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; 4) clear - echo "この機能は開発段階にあるので、お楽しみに!" + send_stats "探偵R起動スクリプト" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7378,15 +8189,15 @@ linux_Oracle() { 6) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "この関数は、彼のおかげで、マスターJHBによって提供されます!" - send_stats "IPv6修正" + echo "この機能は jhb によって提供されています。ありがとう!" + send_stats "IPv6修復" ;; 0) kejilion ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -7398,6 +8209,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7407,7 +8221,7 @@ docker_tato() { if command -v docker &> /dev/null; then echo -e "${gl_kjlan}------------------------" - echo -e "${gl_lv}環境がインストールされています${gl_bai}容器:${gl_lv}$container_count${gl_bai}鏡:${gl_lv}$image_count${gl_bai}ネットワーク:${gl_lv}$network_count${gl_bai}ロール:${gl_lv}$volume_count${gl_bai}" + echo -e "${gl_lv}環境がインストールされました${gl_bai}容器:${gl_lv}$container_count${gl_bai}鏡:${gl_lv}$image_count${gl_bai}ネットワーク:${gl_lv}$network_count${gl_bai}ロール:${gl_lv}$volume_count${gl_bai}" fi } @@ -7415,20 +8229,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}環境がインストールされています${gl_bai} $output $db_output" + echo -e "${gl_lv}環境がインストールされています${gl_bai}サイト:$outputデータベース:$db_output" fi fi @@ -7456,31 +8270,31 @@ linux_ldnmp() { while true; do clear - # send_stats "ldnmp webサイトビルディング" - echo -e "${gl_huang}LDNMP Webサイトビルディング" + # send_stats "LDNMP Web サイトの構築" + echo -e "${gl_huang}LDNMP Web サイトの構築" ldnmp_tato echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}1. ${gl_bai}LDNMP環境をインストールします${gl_huang}★${gl_bai} ${gl_huang}2. ${gl_bai}WordPressをインストールします${gl_huang}★${gl_bai}" - echo -e "${gl_huang}3. ${gl_bai}Discuzフォーラムをインストールします${gl_huang}4. ${gl_bai}Kadao Cloudデスクトップをインストールします" - echo -e "${gl_huang}5. ${gl_bai}Apple CMSフィルムとテレビ局をインストールします${gl_huang}6. ${gl_bai}ユニコーンデジタルカードネットワークをインストールします" - echo -e "${gl_huang}7. ${gl_bai}Flarum Forum Webサイトをインストールします${gl_huang}8. ${gl_bai}Typecho Lightweight Blog Webサイトをインストールします" - echo -e "${gl_huang}9. ${gl_bai}LinkStack共有リンクプラットフォームをインストールします${gl_huang}20. ${gl_bai}動的サイトをカスタマイズします" + echo -e "${gl_huang}1. ${gl_bai}LDNMP環境をインストールする${gl_huang}★${gl_bai} ${gl_huang}2. ${gl_bai}WordPressをインストールする${gl_huang}★${gl_bai}" + echo -e "${gl_huang}3. ${gl_bai}Discuz フォーラムをインストールする${gl_huang}4. ${gl_bai}Kedao クラウド デスクトップをインストールする" + echo -e "${gl_huang}5. ${gl_bai}Apple CMS ムービーおよび TV ステーションをインストールする${gl_huang}6. ${gl_bai}Unicorn デジタル カード ネットワークをインストールする" + echo -e "${gl_huang}7. ${gl_bai}flarumフォーラムWebサイトをインストールする${gl_huang}8. ${gl_bai}typecho 軽量ブログ Web サイトをインストールする" + echo -e "${gl_huang}9. ${gl_bai}LinkStack 共有リンク プラットフォームをインストールする${gl_huang}20. ${gl_bai}カスタム動的サイト" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}21. ${gl_bai}nginxのみをインストールします${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}サイトリダイレクト" - echo -e "${gl_huang}23. ${gl_bai}サイトリバースプロキシ-IP+ポート${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}サイトリバースプロキシ - ドメイン名" - echo -e "${gl_huang}25. ${gl_bai}Bitwardenパスワード管理プラットフォームをインストールします${gl_huang}26. ${gl_bai}HaloブログのWebサイトをインストールします" - echo -e "${gl_huang}27. ${gl_bai}AIペイントプロンプトワードジェネレーターをインストールします${gl_huang}28. ${gl_bai}サイトの逆プロキシロードバランス" - echo -e "${gl_huang}30. ${gl_bai}静的サイトをカスタマイズします" + echo -e "${gl_huang}21. ${gl_bai}nginxのみをインストールする${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}サイトリダイレクト" + echo -e "${gl_huang}23. ${gl_bai}サイト リバース プロキシ - IP+ポート${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}サイト リバース プロキシ ドメイン名" + echo -e "${gl_huang}25. ${gl_bai}Bitwarden パスワード管理プラットフォームをインストールする${gl_huang}26. ${gl_bai}Halo ブログ サイトをインストールする" + echo -e "${gl_huang}27. ${gl_bai}AI絵画プロンプトワードジェネレーターをインストールする${gl_huang}28. ${gl_bai}サイト リバース プロキシ負荷分散" + echo -e "${gl_huang}29. ${gl_bai}ストリーム 4 層プロキシ転送${gl_huang}30. ${gl_bai}カスタム静的サイト" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}31. ${gl_bai}サイトデータ管理${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}サイトデータ全体をバックアップします" - echo -e "${gl_huang}33. ${gl_bai}タイミングのリモートバックアップ${gl_huang}34. ${gl_bai}サイトデータ全体を復元します" + echo -e "${gl_huang}31. ${gl_bai}サイトデータ管理${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}サイト全体のデータをバックアップする" + echo -e "${gl_huang}33. ${gl_bai}スケジュールされたリモートバックアップ${gl_huang}34. ${gl_bai}サイト全体のデータを復元する" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}35. ${gl_bai}LDNMP環境を保護します${gl_huang}36. ${gl_bai}LDNMP環境を最適化します" - echo -e "${gl_huang}37. ${gl_bai}LDNMP環境を更新します${gl_huang}38. ${gl_bai}LDNMP環境をアンインストールします" + echo -e "${gl_huang}35. ${gl_bai}LDNMP環境を保護する${gl_huang}36. ${gl_bai}LDNMP環境の最適化" + echo -e "${gl_huang}37. ${gl_bai}LDNMP環境を更新する${gl_huang}38. ${gl_bai}LDNMP環境をアンインストールする" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_huang}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_huang}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in @@ -7494,25 +8308,30 @@ linux_ldnmp() { 3) clear - # ディスクフォーラム - webname="Discuz论坛" + # ディスカスフォーラム + webname="ディスカスフォーラム" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7520,30 +8339,33 @@ linux_ldnmp() { ldnmp_web_on - echo "データベースアドレス:mysql" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "テーブルプレフィックス:discuz_" + echo "テーブル接頭辞: discuz_" ;; 4) clear - # Kedao Cloudデスクトップ - webname="可道云桌面" + # Kedao クラウド デスクトップ + webname="Kedao クラウド デスクトップ" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7556,29 +8378,33 @@ linux_ldnmp() { restart_ldnmp ldnmp_web_on - echo "データベースアドレス:mysql" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "データベース名:$dbname" - echo "Redisホスト:Redis" + echo "データベース名:$dbname" + echo "redisホスト: redis" ;; 5) clear - # Apple CMS - webname="苹果CMS" + # AppleCMS + webname="AppleCMS" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7595,33 +8421,37 @@ linux_ldnmp() { ldnmp_web_on - echo "データベースアドレス:mysql" - echo "データベースポート:3306" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベースポート: 3306" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "データベースプレフィックス:mac_" + echo "データベース接頭辞: mac_" echo "------------------------" - echo "インストールが成功した後、バックグラウンドアドレスにログインします" + echo "インストールが成功したら、バックエンド アドレスにログインします。" echo "https://$yuming/vip.php" ;; 6) clear - # 一本足のカウントカード - webname="独脚数卡" + # 一本足のナンバーカード + webname="一本足のナンバーカード" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7633,24 +8463,24 @@ linux_ldnmp() { ldnmp_web_on - echo "データベースアドレス:mysql" - echo "データベースポート:3306" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベースポート: 3306" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" echo "" - echo "Redisアドレス:Redis" - echo "Redisパスワード:デフォルトで記入されていません" - echo "Redisポート:6379" + echo "redisアドレス: redis" + echo "redis パスワード: デフォルトでは入力されていません" + echo "Redis ポート: 6379" echo "" - echo "ウェブサイトURL:https://$yuming" - echo "バックグラウンドログインパス: /admin" + echo "ウェブサイトURL:https://$yuming" + echo "バックエンドのログイン パス: /admin" echo "------------------------" - echo "ユーザー名:admin" - echo "パスワード:管理者" + echo "ユーザー名: 管理者" + echo "パスワード: 管理者" echo "------------------------" - echo "ログインするときに右上隅に赤いerror0が表示される場合は、次のコマンドを使用してください。" - echo "また、ユニコーン番号カードがとても面倒で、そのような問題があることに非常に腹を立てています!" + echo "ログイン時に右上隅に赤色の error0 が表示される場合は、次のコマンドを使用してください。" + echo "私も、なぜユニコーンナンバーカードがこんなに面倒で、こんな問題を抱えているのか、とても腹が立っています。" echo "sed -i 's/ADMIN_HTTPS=false/ADMIN_HTTPS=true/g' /home/web/html/$yuming/dujiaoka/.env" ;; @@ -7658,18 +8488,21 @@ linux_ldnmp() { 7) clear # フララムフォーラム - webname="flarum论坛" + webname="フララムフォーラム" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7690,19 +8523,23 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp ldnmp_web_on - echo "データベースアドレス:mysql" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "テーブルプレフィックス:flarum_" - echo "管理者情報は自分で設定されます" + echo "テーブル接頭辞: flarum_" + echo "管理者情報を自分で設定可能" ;; @@ -7711,16 +8548,20 @@ linux_ldnmp() { # typecho webname="typecho" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7735,11 +8576,11 @@ linux_ldnmp() { clear ldnmp_web_on - echo "データベースプレフィックス:typecho_" - echo "データベースアドレス:mysql" - echo "ユーザー名:$dbuse" + echo "データベース接頭辞: typecho_" + echo "データベースアドレス: mysql" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "データベース名:$dbname" + echo "データベース名:$dbname" ;; @@ -7749,17 +8590,20 @@ linux_ldnmp() { # LinkStack webname="LinkStack" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7774,27 +8618,30 @@ linux_ldnmp() { clear ldnmp_web_on - echo "データベースアドレス:mysql" - echo "データベースポート:3306" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベースポート: 3306" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" ;; 20) clear - webname="PHP动态站点" + webname="PHP動的サイト" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7802,10 +8649,10 @@ linux_ldnmp() { cd $yuming clear - echo -e "[${gl_huang}1/6${gl_bai}] PHPソースコードをアップロードします" + echo -e "[${gl_huang}1/6${gl_bai}] PHPソースコードをアップロードする" echo "-------------" - echo "現在、zip-formatソースコードパッケージのみが許可されています。ソースコードパッケージを/home/web/html/に入れてください${yuming}ディレクトリ内" - read -e -p "ダウンロードリンクを入力して、ソースコードパッケージをリモートでダウンロードすることもできます。 Enterを直接押してリモートダウンロードをスキップします。" url_download + echo "現在、zip 形式のソース コード パッケージのみをアップロードできます。ソースコードパッケージを/home/web/html/に置いてください。${yuming}ディレクトリの下" + read -e -p "ダウンロード リンクを入力して、ソース コード パッケージをリモートでダウンロードすることもできます。 Enter を直接押して、リモート ダウンロードをスキップします。" url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -7815,12 +8662,12 @@ linux_ldnmp() { rm -f $(ls -t *.zip | head -n 1) clear - echo -e "[${gl_huang}2/6${gl_bai}] index.phpが配置されているパス" + echo -e "[${gl_huang}2/6${gl_bai}]index.phpが配置されているパス" echo "-------------" # find "$(realpath .)" -name "index.php" -print find "$(realpath .)" -name "index.php" -print | xargs -I {} dirname {} - read -e -p "(/home/web/html/に似たindex.phpのパスを入力してください$yuming/wordpress/): " index_lujing + read -e -p "(/home/web/html/ のような、index.php へのパスを入力してください)$yuming/wordpress/): " index_lujing sed -i "s#root /var/www/html/$yuming/#root $index_lujing#g" /home/web/conf.d/$yuming.conf sed -i "s#/home/web/#/var/www/#g" /home/web/conf.d/$yuming.conf @@ -7828,7 +8675,7 @@ linux_ldnmp() { clear echo -e "[${gl_huang}3/6${gl_bai}] PHPバージョンを選択してください" echo "-------------" - read -e -p "1。PHPの最新バージョン| 2。Php7.4:" pho_v + read -e -p "1.php最新バージョン | 2.php7.4:" pho_v case "$pho_v" in 1) sed -i "s#php:9000#php:9000#g" /home/web/conf.d/$yuming.conf @@ -7839,15 +8686,15 @@ linux_ldnmp() { local PHP_Version="php74" ;; *) - echo "選択の無効な、再入力してください。" + echo "選択が無効です。再入力してください。" ;; esac clear - echo -e "[${gl_huang}4/6${gl_bai}]指定された拡張機能をインストールします" + echo -e "[${gl_huang}4/6${gl_bai}] 指定された拡張機能をインストールします" echo "-------------" - echo "インストールされた拡張機能" + echo "インストールされている拡張機能" docker exec php php -m read -e -p "$(echo -e "输入需要安装的扩展名称,如 ${gl_huang}SourceGuardian imap ftp${gl_bai} 等等。直接回车将跳过安装 : ")" php_extensions @@ -7857,25 +8704,25 @@ linux_ldnmp() { clear - echo -e "[${gl_huang}5/6${gl_bai}]サイト構成を編集します" + echo -e "[${gl_huang}5/6${gl_bai}] サイト構成を編集する" echo "-------------" - echo "任意のキーを押して続行すると、擬似静的コンテンツなど、サイト構成を詳細に設定できます。" + echo "続行するには任意のキーを押してください。擬似静的コンテンツなどのサイト構成を詳細に設定できます。" read -n 1 -s -r -p "" install nano nano /home/web/conf.d/$yuming.conf clear - echo -e "[${gl_huang}6/6${gl_bai}]データベース管理" + echo -e "[${gl_huang}6/6${gl_bai}] データベース管理" echo "-------------" - read -e -p "1.新しいサイトを構築します2。古いサイトを構築し、データベースのバックアップがあります。" use_db + read -e -p "1. 新しいサイトを構築します。 2. 古いサイトを構築し、データベースのバックアップを作成します。" use_db case $use_db in 1) echo ;; 2) - echo "データベースのバックアップは、.GZ-endコンプレッションパッケージである必要があります。 Pagoda/1panelのバックアップデータのインポートをサポートするために、/home/directoryに入れてください。" - read -e -p "ダウンロードリンクを入力して、バックアップデータをリモートでダウンロードすることもできます。 Enterを直接押して、リモートダウンロードをスキップします:" url_download_db + echo "データベースのバックアップは、.gz で終わる圧縮パッケージである必要があります。 Pagoda/1panel バックアップ データのインポートをサポートするには、/home/ ディレクトリに配置してください。" + read -e -p "ダウンロード リンクを入力してバックアップ データをリモートでダウンロードすることもできます。 Enter を直接押して、リモート ダウンロードをスキップします。" url_download_db cd /home/ if [ -n "$url_download_db" ]; then @@ -7885,7 +8732,7 @@ linux_ldnmp() { latest_sql=$(ls -t *.sql | head -n 1) dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname < "/home/$latest_sql" - echo "データベースインポートテーブルデータ" + echo "データベースにインポートされたテーブルデータ" docker exec -i mysql mysql -u root -p"$dbrootpasswd" -e "USE $dbname; SHOW TABLES;" rm -f *.sql echo "データベースのインポートが完了しました" @@ -7900,12 +8747,12 @@ linux_ldnmp() { restart_ldnmp ldnmp_web_on prefix="web$(shuf -i 10-99 -n 1)_" - echo "データベースアドレス:mysql" - echo "データベース名:$dbname" - echo "ユーザー名:$dbuse" + echo "データベースアドレス: mysql" + echo "データベース名:$dbname" + echo "ユーザー名:$dbuse" echo "パスワード:$dbusepasswd" - echo "テーブルプレフィックス:$prefix" - echo "管理者ログイン情報は自分で設定されます" + echo "テーブルの接頭辞:$prefix" + echo "管理者のログイン情報は自分で設定します" ;; @@ -7917,18 +8764,21 @@ linux_ldnmp() { 22) clear - webname="站点重定向" + webname="サイトリダイレクト" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming - read -e -p "ジャンプドメイン名を入力してください:" reverseproxy + read -e -p "リダイレクト ドメイン名を入力してください:" reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7943,7 +8793,7 @@ linux_ldnmp() { find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ポートは、サービスへのアクセスをブロックされています" + echo "IP+ポートはサービスへのアクセスをブロックされています" else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -7953,19 +8803,21 @@ linux_ldnmp() { 24) clear - webname="反向代理-域名" + webname="リバースプロキシドメイン名" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming - echo -e "ドメイン名形式:${gl_huang}google.com${gl_bai}" - read -e -p "抗ジェネレーションドメイン名を入力してください。" fandai_yuming + echo -e "ドメイン名の形式:${gl_huang}google.com${gl_bai}" + read -e -p "リバース プロキシ ドメイン名を入力してください:" fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7979,22 +8831,19 @@ linux_ldnmp() { clear webname="Bitwarden" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8002,32 +8851,30 @@ linux_ldnmp() { clear webname="halo" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; 27) clear - webname="AI绘画提示词生成器" + webname="AI絵画プロンプトワードジェネレーター" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8050,19 +8897,25 @@ linux_ldnmp() { ;; + 29) + stream_panel + ;; + 30) clear - webname="静态站点" + webname="静的サイト" send_stats "インストール$webname" - echo "展開を開始します$webname" + echo "導入を開始する$webname" add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8071,10 +8924,10 @@ linux_ldnmp() { clear - echo -e "[${gl_huang}1/2${gl_bai}]静的ソースコードをアップロードします" + echo -e "[${gl_huang}1/2${gl_bai}] 静的ソースコードをアップロードする" echo "-------------" - echo "現在、zip-formatソースコードパッケージのみが許可されています。ソースコードパッケージを/home/web/html/に入れてください${yuming}ディレクトリ内" - read -e -p "ダウンロードリンクを入力して、ソースコードパッケージをリモートでダウンロードすることもできます。 Enterを直接押してリモートダウンロードをスキップします。" url_download + echo "現在、zip 形式のソース コード パッケージのみをアップロードできます。ソースコードパッケージを/home/web/html/に置いてください。${yuming}ディレクトリの下" + read -e -p "ダウンロード リンクを入力して、ソース コード パッケージをリモートでダウンロードすることもできます。 Enter を直接押して、リモート ダウンロードをスキップします。" url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -8084,12 +8937,12 @@ linux_ldnmp() { rm -f $(ls -t *.zip | head -n 1) clear - echo -e "[${gl_huang}2/2${gl_bai}] index.htmlが配置されているパス" + echo -e "[${gl_huang}2/2${gl_bai}]index.html が配置されているパス" echo "-------------" # find "$(realpath .)" -name "index.html" -print find "$(realpath .)" -name "index.html" -print | xargs -I {} dirname {} - read -e -p "(/home/web/html/に似たindex.htmlへのパスを入力してください$yuming/index/): " index_lujing + read -e -p "(/home/web/html/ のような、index.html へのパスを入力してください)$yuming/index/): " index_lujing sed -i "s#root /var/www/html/$yuming/#root $index_lujing#g" /home/web/conf.d/$yuming.conf sed -i "s#/home/web/#/var/www/#g" /home/web/conf.d/$yuming.conf @@ -8114,31 +8967,33 @@ linux_ldnmp() { 32) clear - send_stats "LDNMP環境バックアップ" + send_stats "LDNMP環境のバックアップ" local backup_filename="web_$(date +"%Y%m%d%H%M%S").tar.gz" - echo -e "${gl_huang}バックアップ$backup_filename ...${gl_bai}" + echo -e "${gl_huang}バックアップ中$backup_filename ...${gl_bai}" cd /home/ && tar czvf "$backup_filename" web while true; do clear - echo "バックアップファイルが作成されました: /home /$backup_filename" - read -e -p "バックアップデータをリモートサーバーに転送しますか? (y/n):" choice + echo "バックアップファイルが作成されました: /home/$backup_filename" + read -e -p "バックアップ データをリモート サーバーに転送しますか? (はい/いいえ):" choice case "$choice" in [Yy]) - read -e -p "リモートサーバーIPを入力してください:" remote_ip + read -e -p "リモートサーバーのIPを入力してください:" remote_ip + read -e -p "ターゲット サーバーの SSH ポート [デフォルト 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then - echo "エラー:リモートサーバーIPを入力してください。" + echo "エラー: リモート サーバーの IP を入力してください。" continue fi local latest_tar=$(ls -t /home/*.tar.gz | head -1) if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" - echo "このファイルは、リモートサーバーホームディレクトリに転送されました。" + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + echo "ファイルはリモート サーバーのホーム ディレクトリに転送されました。" else - echo "転送されるファイルは見つかりませんでした。" + echo "転送するファイルが見つかりませんでした。" fi break ;; @@ -8146,7 +9001,7 @@ linux_ldnmp() { break ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac done @@ -8154,9 +9009,9 @@ linux_ldnmp() { 33) clear - send_stats "タイミングのリモートバックアップ" - read -e -p "リモートサーバーIPを入力してください:" useip - read -e -p "リモートサーバーのパスワードを入力してください:" usepasswd + send_stats "スケジュールされたリモートバックアップ" + read -e -p "リモート サーバーの IP を入力します。" useip + read -e -p "リモートサーバーのパスワードを入力してください:" usepasswd cd ~ wget -O ${useip}_beifen.sh ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/beifen.sh > /dev/null 2>&1 @@ -8166,18 +9021,18 @@ linux_ldnmp() { sed -i "s/123456/$usepasswd/g" ${useip}_beifen.sh echo "------------------------" - echo "1。毎週のバックアップ2。毎日のバックアップ" - read -e -p "選択を入力してください:" dingshi + echo "1. 毎週のバックアップ 2. 毎日のバックアップ" + read -e -p "選択肢を入力してください:" dingshi case $dingshi in 1) check_crontab_installed - read -e -p "毎週のバックアップ(0-6、0は日曜日を表す)の曜日を選択します。" weekday + read -e -p "毎週のバックアップの曜日を選択します (0 ~ 6、0 は日曜日を表します)。" weekday (crontab -l ; echo "0 0 * * $weekday ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; 2) check_crontab_installed - read -e -p "毎日のバックアップの時間を選択します(時間、0-23):" hour + read -e -p "毎日のバックアップ時間 (時間、0 ~ 23) を選択します。" hour (crontab -l ; echo "0 $hour * * * ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; *) @@ -8191,19 +9046,19 @@ linux_ldnmp() { 34) root_use - send_stats "LDNMP環境修復" - echo "利用可能なサイトバックアップ" + send_stats "LDNMP環境の復元" + echo "利用可能なサイトのバックアップ" echo "-------------------------" ls -lt /home/*.gz | awk '{print $NF}' echo "" - read -e -p "入力して最新のバックアップを復元し、バックアップファイル名を入力して指定されたバックアップを復元し、0を入力して終了します。" filename + read -e -p "Enter キーを押して最新のバックアップを復元し、バックアップ ファイル名を入力して指定したバックアップを復元し、0 を入力して終了します。" filename if [ "$filename" == "0" ]; then break_end linux_ldnmp fi - # ユーザーがファイル名を入力しない場合は、最新の圧縮パッケージを使用します + # ユーザーがファイル名を入力しない場合は、最新の圧縮パッケージが使用されます。 if [ -z "$filename" ]; then local filename=$(ls -t /home/*.tar.gz | head -1) fi @@ -8213,16 +9068,15 @@ linux_ldnmp() { docker compose down > /dev/null 2>&1 rm -rf /home/web > /dev/null 2>&1 - echo -e "${gl_huang}減圧が行われています$filename ...${gl_bai}" + echo -e "${gl_huang}解凍中$filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot install_ldnmp else - echo "圧縮パッケージは見つかりませんでした。" + echo "圧縮パッケージが見つかりませんでした。" fi ;; @@ -8240,11 +9094,11 @@ linux_ldnmp() { root_use while true; do clear - send_stats "LDNMP環境を更新します" - echo "LDNMP環境を更新します" + send_stats "LDNMP環境を更新する" + echo "LDNMP環境を更新する" echo "------------------------" ldnmp_v - echo "コンポーネントの新しいバージョンを発見します" + echo "新しいバージョンのコンポーネントが見つかりました" echo "------------------------" check_docker_image_update nginx if [ -n "$update_status" ]; then @@ -8264,13 +9118,13 @@ linux_ldnmp() { fi echo "------------------------" echo - echo "1。更新nginx2。mysql3を更新します。php4を更新します。redisを更新します" + echo "1. nginx を更新します。 2. mysql を更新します。 3. php を更新します。 4. redis を更新します。" echo "------------------------" - echo "5。完全な環境を更新します" + echo "5. 環境全体を更新する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) nginx_upgrade @@ -8279,7 +9133,7 @@ linux_ldnmp() { 2) local ldnmp_pods="mysql" - read -e -p "入力してください${ldnmp_pods}バージョン番号(8.0 8.3 8.4 9.0など)(最新バージョンを取得するには入力):" version + read -e -p "入力してください${ldnmp_pods}バージョン番号 (例: 8.0 8.3 8.4 9.0) (Enter キーを押して最新バージョンを取得します):" version local version=${version:-latest} cd /home/web/ @@ -8290,13 +9144,13 @@ linux_ldnmp() { docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods cp /home/web/docker-compose1.yml /home/web/docker-compose.yml - send_stats "更新します$ldnmp_pods" - echo "更新します${ldnmp_pods}仕上げる" + send_stats "更新する$ldnmp_pods" + echo "更新する${ldnmp_pods}仕上げる" ;; 3) local ldnmp_pods="php" - read -e -p "入力してください${ldnmp_pods}バージョン番号(7.4 8.0 8.1 8.2 8.3)(最新バージョンを入手するには入力):" version + read -e -p "入力してください${ldnmp_pods}バージョン番号 (例: 7.4 8.0 8.1 8.2 8.3) (Enter キーを押して最新バージョンを取得します):" version local version=${version:-8.3} cd /home/web/ cp /home/web/docker-compose.yml /home/web/docker-compose1.yml @@ -8329,8 +9183,8 @@ linux_ldnmp() { docker restart $ldnmp_pods > /dev/null 2>&1 cp /home/web/docker-compose1.yml /home/web/docker-compose.yml - send_stats "更新します$ldnmp_pods" - echo "更新します${ldnmp_pods}仕上げる" + send_stats "更新する$ldnmp_pods" + echo "更新する${ldnmp_pods}仕上げる" ;; 4) @@ -8340,20 +9194,18 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis - send_stats "更新します$ldnmp_pods" - echo "更新します${ldnmp_pods}仕上げる" + send_stats "更新する$ldnmp_pods" + echo "更新する${ldnmp_pods}仕上げる" ;; 5) read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}长时间不更新环境的用户,请慎重更新LDNMP环境,会有数据库更新失败的风险。确定更新LDNMP环境吗?(Y/N): ")" choice case "$choice" in [Yy]) - send_stats "LDNMP環境を完全に更新します" + send_stats "LDNMP環境の完全アップデート" cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8375,7 +9227,7 @@ linux_ldnmp() { 38) root_use - send_stats "LDNMP環境をアンインストールします" + send_stats "LDNMP環境をアンインストールする" read -e -p "$(echo -e "${gl_hong}强烈建议:${gl_bai}先备份全部网站数据,再卸载LDNMP环境。确定删除所有网站数据吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -8389,7 +9241,7 @@ linux_ldnmp() { ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -8399,7 +9251,7 @@ linux_ldnmp() { ;; *) - echo "無効な入力!" + echo "無効な入力です!" esac break_end @@ -8411,2264 +9263,3901 @@ linux_ldnmp() { linux_panel() { - while true; do +local sub_choice="$1" + +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi + +while true; do + + if [ -z "$sub_choice" ]; then clear - # send_stats「アプリマーケット」 echo -e "アプリケーション市場" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Baotaパネルの公式バージョン${gl_kjlan}2. ${gl_bai}Aapanel International Edition" - echo -e "${gl_kjlan}3. ${gl_bai}1パネルの新世代管理パネル${gl_kjlan}4. ${gl_bai}nginxproxymanagerビジュアルパネル" - echo -e "${gl_kjlan}5. ${gl_bai}OpenListマルチストアファイルリストプログラム${gl_kjlan}6. ${gl_bai}UbuntuリモートデスクトップWebエディション" - echo -e "${gl_kjlan}7. ${gl_bai}Nezha Probe VPS監視パネル${gl_kjlan}8. ${gl_bai}QBオフラインBT磁気ダウンロードパネル" - echo -e "${gl_kjlan}9. ${gl_bai}poste.ioメールサーバープログラム${gl_kjlan}10. ${gl_bai}Rocketchatマルチプレイヤーオンラインチャットシステム" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}Zendaoプロジェクト管理ソフトウェア${gl_kjlan}12. ${gl_bai}Qinglongパネルの時限タスク管理プラットフォーム" - echo -e "${gl_kjlan}13. ${gl_bai}CloudReveネットワークディスク${gl_huang}★${gl_bai} ${gl_kjlan}14. ${gl_bai}シンプルな写真ベッド画像管理プログラム" - echo -e "${gl_kjlan}15. ${gl_bai}Emby Multimedia Management System${gl_kjlan}16. ${gl_bai}SpeedTest速度テストパネル" - echo -e "${gl_kjlan}17. ${gl_bai}AdGuardhomeアドウェア${gl_kjlan}18. ${gl_bai}唯一のオフィスオンラインオフィスオフィス" - echo -e "${gl_kjlan}19. ${gl_bai}サンダープールWAFファイアウォールパネル${gl_kjlan}20. ${gl_bai}Portainerコンテナ管理パネル" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}vscode webバージョン${gl_kjlan}22. ${gl_bai}UptimeKuma監視ツール" - echo -e "${gl_kjlan}23. ${gl_bai}メモWebページメモ${gl_kjlan}24. ${gl_bai}webtopリモートデスクトップWebエディション${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}25. ${gl_bai}NextCloudネットワークディスク${gl_kjlan}26. ${gl_bai}QD-Todayタイミングタスク管理フレームワーク" - echo -e "${gl_kjlan}27. ${gl_bai}Dockge Container Stack Managementパネル${gl_kjlan}28. ${gl_bai}librespeed速度テストツール" - echo -e "${gl_kjlan}29. ${gl_bai}searxng集約検索サイト${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}フォトプリズムプライベートアルバムシステム" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}StirlingPDFツールコレクション${gl_kjlan}32. ${gl_bai}Drawio無料のオンラインチャートソフトウェア${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}サンパネルナビゲーションパネル${gl_kjlan}34. ${gl_bai}Pingvin-Shareファイル共有プラットフォーム" - echo -e "${gl_kjlan}35. ${gl_bai}友達のミニマリストのサークル${gl_kjlan}36. ${gl_bai}Lobechataiチャット集約Webサイト" - echo -e "${gl_kjlan}37. ${gl_bai}MyIPツールボックス${gl_huang}★${gl_bai} ${gl_kjlan}38. ${gl_bai}Xiaoya alistファミリーバケット" - echo -e "${gl_kjlan}39. ${gl_bai}Bililive Live Broadcast Recording Tool${gl_kjlan}40. ${gl_bai}WebSH WebバージョンSSH接続ツール" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}マウス管理パネル${gl_kjlan}42. ${gl_bai}NEXTEリモート接続ツール" - echo -e "${gl_kjlan}43. ${gl_bai}Rustdeskリモートデスク(サーバー)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${gl_bai}Rustdeskリモートデスク(リレー)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}45. ${gl_bai}Docker加速ステーション${gl_kjlan}46. ${gl_bai}GitHubアクセラレーションステーション${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}47. ${gl_bai}プロメテウス監視${gl_kjlan}48. ${gl_bai}プロメテウス(ホスト監視)" - echo -e "${gl_kjlan}49. ${gl_bai}プロメテウス(コンテナ監視)${gl_kjlan}50. ${gl_bai}補充監視ツール" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}51. ${gl_bai}PVEチキンパネル${gl_kjlan}52. ${gl_bai}dPanelコンテナ管理パネル" - echo -e "${gl_kjlan}53. ${gl_bai}llama3チャットAIモデル${gl_kjlan}54. ${gl_bai}AMHホストWebサイトビルディングマネジメントパネル" - echo -e "${gl_kjlan}55. ${gl_bai}FRPイントラネット浸透(サーバー側)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${gl_bai}FRPイントラネット浸透(クライアント)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}57. ${gl_bai}deepseekチャットaiビッグモデル${gl_kjlan}58. ${gl_bai}Dify Big Model Knowledge Base${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}59. ${gl_bai}Newapi Big Model Asset Management${gl_kjlan}60. ${gl_bai}Jumpserverオープンソースバス剤マシン" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}61. ${gl_bai}オンライン翻訳サーバー${gl_kjlan}62. ${gl_bai}Ragflow Big Model Knowledge Base" - echo -e "${gl_kjlan}63. ${gl_bai}OpenWebui自己ホストAIプラットフォーム${gl_huang}★${gl_bai} ${gl_kjlan}64. ${gl_bai}IT-Toolsツールボックス" - echo -e "${gl_kjlan}65. ${gl_bai}N8Nオートメーションワークフロープラットフォーム${gl_huang}★${gl_bai} ${gl_kjlan}66. ${gl_bai}YT-DLPビデオダウンロードツール" - echo -e "${gl_kjlan}67. ${gl_bai}DDNS-GOダイナミックDNS管理ツール${gl_huang}★${gl_bai} ${gl_kjlan}68. ${gl_bai}AllinsSL証明書管理プラットフォーム" - echo -e "${gl_kjlan}69. ${gl_bai}SFTPGOファイル転送ツール${gl_kjlan}70. ${gl_bai}アストロボットチャットロボットフレームワーク" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}71. ${gl_bai}Navidromeプライベートミュージックサーバー${gl_kjlan}72. ${gl_bai}Bitwardenパスワードマネージャー${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}73. ${gl_bai}libretvプライベート映画とテレビ${gl_kjlan}74. ${gl_bai}MOONTVプライベート映画" - echo -e "${gl_kjlan}75. ${gl_bai}メロディーミュージックエルフ${gl_kjlan}76. ${gl_bai}オンラインDOS古いゲーム" - echo -e "${gl_kjlan}77. ${gl_bai}サンダーオフラインダウンロードツール${gl_kjlan}78. ${gl_bai}Pandawikiインテリジェントドキュメント管理システム" - echo -e "${gl_kjlan}79. ${gl_bai}Beszelサーバーの監視" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + echo -e "${gl_kjlan}-------------------------" - case $sub_choice in - 1) + local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" + # ループで色を設定する + for i in {1..150}; do + if echo "$app_numbers" | grep -q "^$i$"; then + declare "color$i=${gl_lv}" + else + declare "color$i=${gl_bai}" + fi + done + + echo -e "${gl_kjlan}1. ${color1}パゴダパネル正式版${gl_kjlan}2. ${color2}aaPanel パゴダ国際版" + echo -e "${gl_kjlan}3. ${color3}1Panel 新世代管理パネル${gl_kjlan}4. ${color4}NginxProxyManager 視覚化パネル" + echo -e "${gl_kjlan}5. ${color5}OpenList マルチストア ファイル リスト プログラム${gl_kjlan}6. ${color6}Ubuntu リモート デスクトップ Web エディション" + echo -e "${gl_kjlan}7. ${color7}Nezha Probe VPS 監視パネル${gl_kjlan}8. ${color8}QBオフラインBT磁気ダウンロードパネル" + echo -e "${gl_kjlan}9. ${color9}Poste.io メール サーバー プログラム${gl_kjlan}10. ${color10}RocketChat 複数人オンライン チャット システム" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}11. ${color11}ZenTao プロジェクト管理ソフトウェア${gl_kjlan}12. ${color12}Qinglong パネルのスケジュールされたタスク管理プラットフォーム" + echo -e "${gl_kjlan}13. ${color13}Cloudreve ネットワークディスク${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}シンプルなピクチャーベッド画像管理プログラム" + echo -e "${gl_kjlan}15. ${color15}emby マルチメディア管理システム${gl_kjlan}16. ${color16}Speedtest スピードテストパネル" + echo -e "${gl_kjlan}17. ${color17}AdGuardHome はアドウェアを削除します${gl_kjlan}18. ${color18}Onlyofficeオンラインオフィス OFFICE" + echo -e "${gl_kjlan}19. ${color19}Leichi WAF ファイアウォール パネル${gl_kjlan}20. ${color20}ポーターコンテナ管理パネル" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}21. ${color21}VScode Web バージョン${gl_kjlan}22. ${color22}UptimeKuma監視ツール" + echo -e "${gl_kjlan}23. ${color23}メモウェブメモ${gl_kjlan}24. ${color24}Webtop リモート デスクトップ Web バージョン${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}25. ${color25}Nextcloud ネットワーク ディスク${gl_kjlan}26. ${color26}QD-Today スケジュールされたタスク管理フレームワーク" + echo -e "${gl_kjlan}27. ${color27}Dockge コンテナ スタック管理パネル${gl_kjlan}28. ${color28}LibreSpeed 速度テストツール" + echo -e "${gl_kjlan}29. ${color29}searxng 集約検索ステーション${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrismプライベートアルバムシステム" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}31. ${color31}StirlingPDF ツール コレクション${gl_kjlan}32. ${color32}無料のオンライングラフ作成ソフトウェアdrawio${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${color33}Sun-Panel ナビゲーション パネル${gl_kjlan}34. ${color34}Pingvin-Share ファイル共有プラットフォーム" + echo -e "${gl_kjlan}35. ${color35}ミニマリストの友達の輪${gl_kjlan}36. ${color36}LobeChatAIチャットアグリゲーションサイト" + echo -e "${gl_kjlan}37. ${color37}MyIP ツールボックス${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}Xiaoya alistファミリーバケット" + echo -e "${gl_kjlan}39. ${color39}Bililive ライブ配信録画ツール${gl_kjlan}40. ${color40}webssh Web版 SSH接続ツール" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}41. ${color41}マウス管理パネル${gl_kjlan}42. ${color42}Nexterm リモート接続ツール" + echo -e "${gl_kjlan}43. ${color43}RustDesk リモート デスクトップ (サーバー)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk リモート デスクトップ (リレー)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}45. ${color45}Docker アクセラレーション ステーション${gl_kjlan}46. ${color46}GitHub アクセラレーション ステーション${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}47. ${color47}プロメテウスの監視${gl_kjlan}48. ${color48}Prometheus (ホスト監視)" + echo -e "${gl_kjlan}49. ${color49}Prometheus (コンテナ監視)${gl_kjlan}50. ${color50}補充監視ツール" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}51. ${color51}PVEオープンチックパネル${gl_kjlan}52. ${color52}DPanel コンテナ管理パネル" + echo -e "${gl_kjlan}53. ${color53}llama3チャットAI大型モデル${gl_kjlan}54. ${color54}AMH ホスト Web サイト構築管理パネル" + echo -e "${gl_kjlan}55. ${color55}FRPイントラネット普及(サーバー)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRPイントラネット普及(クライアント)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}57. ${color57}ディープシークチャットAI大型モデル${gl_kjlan}58. ${color58}Dify 大規模モデルのナレッジ ベース${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}59. ${color59}NewAPI 大規模モデル資産管理${gl_kjlan}60. ${color60}JumpServer オープンソース要塞マシン" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}61. ${color61}オンライン翻訳サーバー${gl_kjlan}62. ${color62}RAGFlow 大規模モデルのナレッジ ベース" + echo -e "${gl_kjlan}63. ${color63}OpenWebUI セルフホスト型 AI プラットフォーム${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}ITツールツールボックス" + echo -e "${gl_kjlan}65. ${color65}n8n自動ワークフロープラットフォーム${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp ビデオ ダウンロード ツール" + echo -e "${gl_kjlan}67. ${color67}ddns-go ダイナミック DNS 管理ツール${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL 証明書管理プラットフォーム" + echo -e "${gl_kjlan}69. ${color69}SFTPGo ファイル転送ツール${gl_kjlan}70. ${color70}AstrBot チャットボット フレームワーク" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}71. ${color71}Navidrome プライベート ミュージック サーバー${gl_kjlan}72. ${color72}bitwarden パスワードマネージャー${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}73. ${color73}LibreTV プライベートムービー${gl_kjlan}74. ${color74}MoonTV のプライベート ムービー" + echo -e "${gl_kjlan}75. ${color75}メロディー音楽の魔法使い${gl_kjlan}76. ${color76}オンライン DOS 古いゲーム" + echo -e "${gl_kjlan}77. ${color77}Thunder オフライン ダウンロード ツール${gl_kjlan}78. ${color78}PandaWiki インテリジェント文書管理システム" + echo -e "${gl_kjlan}79. ${color79}Beszel サーバーの監視${gl_kjlan}80. ${color80}リンクワーデンのブックマーク管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet ビデオ会議${gl_kjlan}82. ${color82}gpt-load 高性能 AI 透過プロキシ" + echo -e "${gl_kjlan}83. ${color83}komariサーバー監視ツール${gl_kjlan}84. ${color84}Wallos の個人財務管理ツール" + echo -e "${gl_kjlan}85. ${color85}イミッチ・ピクチャー・ビデオ・マネージャー${gl_kjlan}86. ${color86}ジェリーフィンメディア管理システム" + echo -e "${gl_kjlan}87. ${color87}SyncTV は一緒に映画を見るための素晴らしいツールです${gl_kjlan}88. ${color88}Owncast の自己ホスト型ライブ ストリーミング プラットフォーム" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox ファイルエクスプレス${gl_kjlan}90. ${color90}マトリックス分散型チャットプロトコル" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea プライベート コード リポジトリ${gl_kjlan}92. ${color92}FileBrowser ファイルマネージャー" + echo -e "${gl_kjlan}93. ${color93}Dufs のミニマリスト静的ファイル サーバー${gl_kjlan}94. ${color94}Gopeed高速ダウンロードツール" + echo -e "${gl_kjlan}95. ${color95}ペーパーレス文書管理プラットフォーム${gl_kjlan}96. ${color96}2FAuth セルフホスト型 2 段階認証システム" + echo -e "${gl_kjlan}97. ${color97}WireGuard ネットワーキング (サーバー)${gl_kjlan}98. ${color98}WireGuard ネットワーキング (クライアント)" + echo -e "${gl_kjlan}99. ${color99}DSM Synology 仮想マシン${gl_kjlan}100. ${color100}Syncthing ピアツーピア ファイル同期ツール" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI動画生成ツール${gl_kjlan}102. ${color102}VoceChat 複数人オンライン チャット システム" + echo -e "${gl_kjlan}103. ${color103}Umami ウェブサイト統計ツール${gl_kjlan}104. ${color104}ストリーム 4 層プロキシ転送ツール" + echo -e "${gl_kjlan}105. ${color105}思源ノート${gl_kjlan}106. ${color106}Drawnix オープンソース ホワイトボード ツール" + echo -e "${gl_kjlan}107. ${color107}PanSou ネットワークディスク検索${gl_kjlan}108. ${color108}LangBot チャットボット" + echo -e "${gl_kjlan}109. ${color109}ZFileオンラインネットワークディスク${gl_kjlan}110. ${color110}カラオケのブックマーク管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}マルチフォーマットファイル変換ツール${gl_kjlan}112. ${color112}Lucky 大規模イントラネット侵入ツール" + echo -e "${gl_kjlan}113. ${color113}Firefoxブラウザ" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}サードパーティ製アプリケーションのリスト" + echo -e "${gl_kjlan}あなたのアプリをここに表示したいですか?開発者ガイドを確認してください。${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # アプリの説明を取得する + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # インストールステータスを確認します (appno.txt の ID と一致します)。 + # ここでは、appno.txtに記録されているのはbase_name(つまりファイル名)であると仮定します。 + if echo "$app_numbers" | grep -q "^$base_name$"; then + # インストールされている場合: showbase_name - description [インストール済み] (緑色) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text[インストール済み]${gl_bai}" + else + # インストールされていない場合:通常通り表示 + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } - panel_app_manage() { - bt - } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}すべてのアプリケーション データをバックアップする${gl_kjlan}r. ${gl_bai}すべてのアプリデータを復元する" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "選択肢を入力してください:" sub_choice + fi - install_panel + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="パゴダパネル" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } + panel_app_manage() { + bt + } + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - ;; - 2) + install_panel - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } - panel_app_manage() { - bt - } + ;; + 2|aapanel) - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } - install_panel + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - ;; - 3) + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + panel_app_manage() { + bt + } - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + install_panel - panel_app_uninstall() { - 1pctl uninstall - } + ;; + 3|1p|1panel) - install_panel + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - ;; - 4) + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - docker_rum() { + panel_app_uninstall() { + 1pctl uninstall + } - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + install_panel + ;; + 4|npm) - } + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" + docker_rum() { - docker_app + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - ;; - 5) + } - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + local docker_describe="ドメイン名アクセスの追加をサポートしていない Nginx リバース プロキシ ツール パネル。" + local docker_url="公式サイト紹介:https://nginxproxymanager.com/" + local docker_use="echo \"初期ユーザー名: admin@example.com\"" + local docker_passwd="echo \"初期パスワード:changeme\"" + local app_size="1" - docker_rum() { + docker_app - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + ;; - } + 5|openlist) + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - 6) + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 + + } - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 - docker_rum() { + local docker_describe="gin と Solidjs を利用した、複数のストレージ、Web ブラウジング、WebDAV をサポートするファイル一覧プログラム" + local docker_url="公式サイト紹介:https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "ログインユーザー名を設定します:" admin + read -e -p "ログインユーザーのパスワードを設定します。" admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - } + } - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + local docker_describe="webtop は Ubuntu ベースのコンテナです。 IP にアクセスできない場合は、アクセス用のドメイン名を追加してください。" + local docker_url="公式Webサイトの紹介:https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - ;; - 7) + ;; + 7|nezha) + clear + send_stats "ネザを構築する" + + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "ネザを作る" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "Nezhaの監視$check_docker $update_status" - echo "オープンソース、軽量で使いやすいサーバーの監視と操作およびメンテナンスツール" - echo "公式ウェブサイトの建設文書:https://nezha.wiki/guide/dashboard.html" - if docker inspect "$docker_name" &>/dev/null; then + echo -e "ネザモニタリング$check_docker $update_status" + echo "オープンソースの軽量で使いやすいサーバー監視および運用保守ツール" + echo "公式 Web サイト構築ドキュメント: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. 使用する" + echo "------------------------" + echo "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択内容を入力してください:" choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1。使用します" - echo "------------------------" - echo "0。前のメニューに戻ります" - echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent オフライン BT 磁気ダウンロード サービス" + local docker_url="公式サイト紹介:https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "郵便局を建てる" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "郵便サービス$check_docker $update_status" + echo "poste.io はオープンソースのメール サーバー ソリューションです。" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "ポート検出" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}ポート$port現在利用可能${gl_bai}" + else + echo -e "${gl_hong}ポート$port現在利用不可${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "訪問先住所:" + echo "https://$yuming" + fi - 9) - send_stats "郵便局を建設します" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. インストール 2. アップデート 3. アンインストール" + echo "------------------------" + echo "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択内容を入力してください:" choice - clear - echo -e "郵便局サービス$check_docker $update_status" - echo "Poste.ioはオープンソースメールサーバーソリューションです。" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1wv421c71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "電子メールのドメイン名を設定してください (例: mail.yuming.com)。" yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "まずこれらの DNS レコードを解析します" + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "続行するには任意のキーを押してください..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "ポート検出" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}ポート$port現在利用可能です${gl_bai}" - else - echo -e "${gl_hong}ポート$port現在利用できません${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io - if docker inspect "$docker_name" &>/dev/null; then - yuming=$(cat /home/docker/mail.txt) - echo "アクセスアドレス:" + + add_app_id + + clear + echo "poste.ioがインストールされました" + echo "------------------------" + echo "次のアドレスを使用して poste.io にアクセスできます。" echo "https://$yuming" - fi + echo "" - echo "------------------------" - echo "1。インストール2。更新3。アンインストール" - echo "------------------------" - echo "0。前のメニューに戻ります" - echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "たとえば、mail.yuming.comなど、電子メールドメイン名を設定してください。" yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "これらのDNSレコードを最初に解析します" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "任意のキーを押して続行します..." - read -n 1 -s -r -p "" + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i + yuming=$(cat /home/docker/mail.txt) + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.ioがインストールされました" + echo "------------------------" + echo "次のアドレスを使用して poste.io にアクセスできます。" + echo "https://$yuming" + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "アプリがアンインストールされました" + ;; - install jq - install_docker + *) + break + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + esac + break_end + done - clear - echo "Poste.ioがインストールされています" - echo "------------------------" - echo "次のアドレスを使用してposte.ioにアクセスできます。" - echo "https://$yuming" - echo "" + ;; - ;; + 10|rocketchat) - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - clear - echo "Poste.ioがインストールされています" - echo "------------------------" - echo "次のアドレスを使用してposte.ioにアクセスできます。" - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - echo "アプリはアンインストールされています" - ;; + local app_id="10" + local app_name="Rocket.Chat チャット システム" + local app_text="Rocket.Chat は、リアルタイム チャット、音声およびビデオ通話、ファイル共有、その他の機能をサポートするオープンソースのチーム コミュニケーション プラットフォームです。" + local app_url="公式紹介:https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - *) - break - ;; + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - esac - break_end - done + clear + ip_address + echo "インストール完了" + check_docker_app_ip + } - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "rocket.chat がインストールされました" + check_docker_app_ip + } - 10) + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "アプリがアンインストールされました" + } - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + docker_app_plus + ;; - clear - ip_address - echo "インストール" - check_docker_app_ip - } - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "Rocket.chatがインストールされています" - check_docker_app_ip - } - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "アプリはアンインストールされています" - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_plus - ;; + docker_rum() { - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - docker_rum() { + } + local docker_describe="ZenTao はユニバーサルなプロジェクト管理ソフトウェアです" + local docker_url="公式サイト紹介:https://www.zentao.net/" + local docker_use="echo \"初期ユーザー名: admin\"" + local docker_passwd="echo 「初期パスワード: 123456」" + local app_size="2" + docker_app - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + ;; + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 - } + docker_rum() { - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app - ;; + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 - docker_rum() { + } + local docker_describe="Qinglong Panel はスケジュールされたタスク管理プラットフォームです" + local docker_url="公式サイト紹介:${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + ;; + 13|cloudreve) + + local app_id="13" + local app_name="クラウドリーブネットワークディスク" + local app_text="Cloudreve は、複数のクラウド ストレージをサポートするネットワーク ディスク システムです。" + local app_url="ビデオ紹介: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 13) + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "アプリがアンインストールされました" + } - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "インストール" - check_docker_app_ip - } + docker_app_plus + ;; + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + } + local docker_describe="シンプルドローイングベッドはシンプルなドローイングベッドプログラムです" + local docker_url="公式サイト紹介:${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "アプリはアンインストールされています" - } + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_plus - ;; + docker_rum() { - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 + } - docker_rum() { - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + local docker_describe="emby は、サーバー上でビデオとオーディオを整理し、クライアント デバイスにオーディオとビデオをストリーミングするために使用できるマスター/スレーブ アーキテクチャのメディア サーバー ソフトウェアです。" + local docker_url="公式サイト紹介:https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server + } - docker_rum() { + local docker_describe="Speedtest 速度測定パネルは、複数のテスト機能を備えた VPS ネットワーク速度テスト ツールで、VPS のインバウンドおよびアウトバウンドのトラフィックをリアルタイムで監視することもできます。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server + ;; + 17|adguardhome) - } + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; - 17) + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 - docker_rum() { + } - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local docker_describe="AdGuardHome は、将来的には単なる DNS サーバー以上のネットワーク全体の広告ブロックおよび追跡防止ソフトウェアです。" + local docker_url="公式サイト紹介:https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + 18|onlyoffice) - ;; + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 + docker_rum() { - 18) + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 - docker_rum() { + } - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + local docker_describe="Onlyoffice は、非常に強力なオープンソースのオンライン オフィス ツールです。" + local docker_url="公式サイト紹介:https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; - } + 19|safeline) + send_stats "雷のプールを作る" - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "サンダープールサービス$check_docker" + echo "Leichi は、Changting Technology によって開発された WAF サイト ファイアウォール プログラム パネルで、自動防御のためにサイトを反転できます。" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" - ;; + echo "------------------------" + echo "1. インストール 2. アップデート 3. パスワードのリセット 4. アンインストール" + echo "------------------------" + echo "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択内容を入力してください:" choice - 19) - send_stats "サンダープールを構築します" + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "サンダープールサービス$check_docker" - echo "Lei Chiは、Changting Technologyによって開発されたWAFサイトファイアウォールプログラムパネルであり、自動防衛のために代理店サイトを逆転させることができます。" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1mz421t74c?t=0.1" - if docker inspect "$docker_name" &>/dev/null; then + add_app_id + clear + echo "Leichi WAFパネルを導入しました" check_docker_app_ip - fi - echo "" + docker exec safeline-mgt resetadmin - echo "------------------------" - echo "1。インストール2。更新3。パスワードのリセット4。アンインストール" - echo "------------------------" - echo "0。前のメニューに戻ります" - echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + ;; + + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "Leichi WAF パネルが更新されました" + check_docker_app_ip + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "デフォルトのインストール ディレクトリにいる場合、プロジェクトはすでにアンインストールされています。インストール ディレクトリをカスタマイズする場合は、インストール ディレクトリに移動して自分で実行する必要があります。" + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer は軽量の Docker コンテナ管理パネルです" + local docker_url="公式サイト紹介:https://www.porttainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode は強力なオンライン コード作成ツールです" + local docker_url="公式サイト紹介:${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="Uptime Kuma 使いやすいセルフホスト型監視ツール" + local docker_url="公式サイト紹介:${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos は軽量の自己ホスト型メモ センターです" + local docker_url="公式サイト紹介:${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "ログインユーザー名を設定します:" admin + read -e -p "ログインユーザーのパスワードを設定します。" admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="Webtop は、Alpine コンテナの中国語版に基づいています。 IP にアクセスできない場合は、アクセス用のドメイン名を追加してください。" + local docker_url="公式Webサイトの紹介:https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="400,000 を超える導入実績を持つ Nextcloud は、ダウンロードできる最も人気のあるローカル コンテンツ コラボレーション プラットフォームです。" + local docker_url="公式サイト紹介:https://nextcloud.com/" + local docker_use="echo \"アカウント: nextcloud パスワード:$rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today は、HTTP リクエストのスケジュールされたタスク自動実行フレームワークです。" + local docker_url="公式サイト紹介:https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="dockge は、視覚的な docker-compose コンテナー管理パネルです。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed は、JavaScript で実装され、すぐに使用できる軽量の速度テスト ツールです。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng は非公開の検索エンジン サイトです。" + local docker_url="公式サイト紹介:https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="Photoprism は非常に強力なプライベート フォト アルバム システムです" + local docker_url="公式サイト紹介:https://www.photoprism.app/" + local docker_use="echo \"アカウント: admin パスワード:$rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="これは、Docker を使用してローカルでホストされる強力な Web ベースの PDF 操作ツールで、PDF ファイルに対して分割マージ、変換、再編成、画像の追加、回転、圧縮などのさまざまな操作を実行できます。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="これは強力なグラフ作成ソフトウェアです。マインド マップ、トポロジ図、フローチャートを描画できます。" + local docker_url="公式サイト紹介:https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel サーバー、NAS ナビゲーション パネル、ホームページ、ブラウザーのホームページ" + local docker_url="公式サイト紹介:https://doc.sun-panel.top/zh_cn/" + local docker_use="echo 「アカウント: admin@sun.cc パスワード: 12345678」" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share は自己構築可能なファイル共有プラットフォームであり、WeTransfer の代替品です" + local docker_url="公式サイト紹介:${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="ミニマリストの瞬間、模倣性の高いWeChatの瞬間、あなたの素晴らしい人生を記録してください" + local docker_url="公式サイト紹介:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo 「アカウント: admin パスワード: a123456」" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat は、市場で主流の AI 大型モデル、ChatGPT/Claude/Gemini/Groq/Ollama を集約しています。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="独自の IP 情報と接続性を表示し、Web パネルを使用して表示できる多機能 IP ツールボックスです。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "シャオヤファミリーバケツ" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go は、複数のライブ ブロードキャスト プラットフォームをサポートするライブ ブロードキャスト録画ツールです" + local docker_url="公式サイト紹介:${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="シンプルなオンライン SSH 接続ツールと SFTP ツール" + local docker_url="公式サイト紹介:${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="マウスパネル" + local panelurl="正式な住所:${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm は、強力なオンライン SSH/VNC/RDP 接続ツールです。" + local docker_url="公式サイト紹介:${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="Rustdesk のオープンソース リモート デスクトップ (サーバー) は、自社の Sunflower プライベート サーバーに似ています。" + local docker_url="公式サイト紹介:https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"リモート デスクトップ クライアントで使用される IP とキーを記録します。オプション 44 に進んでリレーをインストールしてください!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="Rustdesk のオープンソース リモート デスクトップ (リレー) は、独自の Sunflower プライベート サーバーに似ています。" + local docker_url="公式サイト紹介:https://rustdesk.com/zh-cn/" + local docker_use="echo \"公式 Web サイトにアクセスして、リモート デスクトップ クライアントをダウンロードします: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry は、Docker イメージを保存および配布するためのサービスです。" + local docker_url="公式サイト紹介:https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="Go を使用して実装された GHProxy は、一部の領域で Github リポジトリのプルを高速化するために使用されます。" + local docker_url="公式サイト紹介:https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="プロメテウスの監視" + local app_text="Prometheus+Grafana エンタープライズレベルの監視システム" + local app_url="公式サイト紹介:https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "インストール完了" + check_docker_app_ip + echo "初期のユーザー名とパスワードは次のとおりです: admin" + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "アプリがアンインストールされました" + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="これは Prometheus ホスト データ収集コンポーネントです。監視対象ホストにデプロイしてください。" + local docker_url="公式サイト紹介:https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="これは Prometheus コンテナのデータ収集コンポーネントです。監視対象ホストにデプロイしてください。" + local docker_url="公式サイト紹介:https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="これは、Web サイトの変更の検出、補充の監視、通知を行うための小さなツールです。" + local docker_url="公式サイト紹介:https://github.com/dgtlmoon/changedetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE オープンひよこ" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker ビジュアル パネル システムは、完全な Docker 管理機能を提供します。" + local docker_url="公式サイト紹介:https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI は、新しい llama3 ラージ言語モデルに接続されているラージ言語モデル Web ページ フレームワークです。" + local docker_url="公式サイト紹介:https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMHパネル" + local panelurl="公式アドレス:https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI は、新しい DeepSeek R1 大規模言語モデルに接続されている大規模言語モデル Web ページ フレームワークです。" + local docker_url="公式サイト紹介:https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="Difyナレッジベース" + local app_text="これは、オープンソースの大規模言語モデル (LLM) アプリケーション開発プラットフォームです。 AI生成用の自己ホスト型トレーニングデータ" + local app_url="公式ウェブサイト:https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "インストール完了" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "アプリがアンインストールされました" + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="新世代の大型モデルゲートウェイとAI資産管理システム" + local app_url="公式サイト:https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "アプリがアンインストールされました" + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer オープンソース要塞マシン" + local app_text="これは、オープンソースの特権アクセス管理 (PAM) ツールです。このプログラムはポート 80 を占有しているため、アクセス用のドメイン名の追加はサポートされていません。" + local app_url="公式紹介: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "インストール完了" + check_docker_app_ip + echo "初期ユーザー名: admin" + echo "初期パスワード:ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "アプリが更新されました" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "アプリがアンインストールされました" + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="無料のオープンソース機械翻訳 API は完全に自己ホストされており、その翻訳エンジンはオープンソースの Argos Translate ライブラリを利用しています。" + local docker_url="公式サイト紹介:https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow ナレッジベース" + local app_text="ドキュメントの深い理解に基づくオープンソース RAG (Retrieval Augmented Generation) エンジン" + local app_url="公式ウェブサイト:https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "アプリがアンインストールされました" + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI は大規模な言語モデルの Web ページ フレームワークであり、公式の簡易バージョンではすべての主要モデルへの API アクセスがサポートされています。" + local docker_url="公式サイト紹介:https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="開発者と IT ワーカーにとって非常に便利なツール" + local docker_url="公式サイト紹介:https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="強力な自動ワークフロー プラットフォームです" + local docker_url="公式サイト紹介:https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="パブリック IP (IPv4/IPv6) を主要な DNS サービス プロバイダーにリアルタイムで自動的に更新し、動的なドメイン名解決を実現します。" + local docker_url="公式サイト紹介:https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="オープンソースの無料 SSL 証明書自動化管理プラットフォーム" + local docker_url="公式サイト紹介:https://allinssl.com" + local docker_use="echo \"セキュリティの入り口: /allinssl\"" + local docker_passwd="echo \"ユーザー名: allinssl パスワード: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="オープンソースでいつでもどこでも無料の SFTP FTP WebDAV ファイル転送ツール" + local docker_url="公式サイト紹介:https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="オープンソース AI チャットボット フレームワーク。WeChat、QQ、TG による大規模 AI モデルへのアクセスをサポート" + local docker_url="公式サイト紹介:https://astrbot.app/" + local docker_use="echo \"ユーザー名: astrbot パスワード: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="軽量で高性能な音楽ストリーミングサーバーです" + local docker_url="公式サイト紹介:https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="データを管理できるパスワード マネージャー" + local docker_url="公式サイト紹介:https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "LibreTV のログイン パスワードを設定します。" app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="無料のオンラインビデオ検索および視聴プラットフォーム" + local docker_url="公式サイト紹介:https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="MoonTV プライベート映画とテレビ" + local app_text="無料のオンラインビデオ検索および視聴プラットフォーム" + local app_url="ビデオ紹介: https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "ログインユーザー名を設定します:" admin + read -e -p "ログインユーザーのパスワードを設定します。" admin_password + read -e -p "認証コードを入力してください:" shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "アプリがアンインストールされました" + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - clear - echo "サンダープールWAFパネルがインストールされています" - check_docker_app_ip - docker exec safeline-mgt resetadmin + docker_rum() { - ;; + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - clear - echo "サンダープールWAFパネルが更新されました" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - echo "デフォルトのインストールディレクトリである場合、プロジェクトはアンインストールされました。インストールディレクトリをカスタマイズする場合は、インストールディレクトリにアクセスして自分で実行する必要があります。" - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; - esac - break_end - done + } - ;; + local docker_describe="音楽をより適切に管理できるように設計された音楽ウィザード。" + local docker_url="公式サイト紹介:https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 - docker_rum() { + ;; - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer - } + 76|dosgame) + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest - ;; + } - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 + local docker_describe="中華DOSゲームまとめサイトです" + local docker_url="公式サイト紹介:https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server + 77|xunlei) - } + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 + docker_rum() { - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + read -e -p "ログインユーザー名を設定します:" app_use + read -e -p "ログインパスワードを設定します:" app_passwd + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei - docker_rum() { + } - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + local docker_describe="Xunlei、オフライン高速 BT 磁気ダウンロード ツール" + local docker_url="公式サイト紹介:https://github.com/cnk3x/xunlei" + local docker_use="echo \"携帯電話で Xunlei にログインし、招待コードを入力してください。招待コード: Xunlei Niutong\"" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 + 78|PandaWiki) - docker_rum() { + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki は、AI 大型モデルによって駆動されるオープンソースのインテリジェントな文書管理システムです。ポートの展開をカスタマイズしないことを強くお勧めします。" + local app_url="公式紹介: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } - } + docker_app_update() { + docker_app_install + } - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 + docker_app_uninstall() { + docker_app_install + } - docker_rum() { + docker_app_plus + ;; - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest + 79|beszel) - } + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 + docker_rum() { - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + } - docker_rum() { + local docker_describe="Beszel は軽量で使いやすいサーバー監視です" + local docker_url="公式サイト紹介:https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + ;; - } - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; + 80|linkwarden) - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + local app_id="80" + local app_name="リンクワーデンのブックマーク管理" + local app_text="タグ付け、検索、チーム コラボレーションをサポートするオープンソースの自己ホスト型ブックマーク管理プラットフォーム。" + local app_url="公式サイト:https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - docker_rum() { + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + # 公式の docker-compose および env ファイルをダウンロードする + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" - } + # ランダムなキーとパスワードを生成する + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env - docker_rum() { + # 管理者アカウント情報を追加する + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - } + # コンテナの起動 + docker compose up -d - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + clear + echo "インストール完了" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # 元の変数を保持する + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "アプリがアンインストールされました" + } + + docker_app_plus - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 + ;; - docker_rum() { - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest - } + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet ビデオ会議" + local app_text="複数人でのオンライン会議、画面共有、暗号化通信をサポートするオープンソースの安全なビデオ会議ソリューション。" + local app_url="公式サイト:https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_install() { - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - docker_rum() { + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng + } - } + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "アプリがアンインストールされました" + } - docker_rum() { + docker_app_plus - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + ;; - } - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 82|gpt-load) + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 + read -e -p "設定${docker_name}ログイン キー (sk- で始まる文字と数字の組み合わせ) 例: sk-159kejilionyyds163:" app_passwd - docker_rum() { + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + } - } + local docker_describe="高性能AIインターフェース透過プロキシサービス" + local docker_url="公式サイト紹介:https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 - docker_rum() { + 83|komari) - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - } + docker_rum() { - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + } - docker_rum() { + local docker_describe="軽量のセルフホスト型サーバー監視ツール" + local docker_url="公式サイト紹介:https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"デフォルトのアカウント: admin デフォルトのパスワード: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + ;; - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 + 84|wallos) - docker_rum() { + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } + docker_rum() { + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="公式ウェブサイトの紹介:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="財務管理用のオープンソースの個人サブスクリプション トラッカー" + local docker_url="公式サイト紹介:https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + 85|immich) - docker_rum() { + local app_id="85" + local app_name="イミッチ・ピクチャー・ビデオ・マネージャー" + local app_text="高性能の自己ホスト型写真およびビデオ管理ソリューション。" + local app_url="公式サイト紹介:https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + docker compose up -d - docker_rum() { + clear + echo "インストール完了" + check_docker_app_ip - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + } - } + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "アプリがアンインストールされました" + } - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_plus - 38) - send_stats "Xiaoyaファミリーバケット" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; - 39) + ;; + + + 86|jellyfin) + + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 + + docker_rum() { + + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin + + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin + + + } + + local docker_describe="オープンソースのメディアサーバーソフトウェアです" + local docker_url="公式サイト紹介:https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 87|synctv) + + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 + + docker_rum() { + + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv + + } + + local docker_describe="リモートで映画や生放送を一緒に見るプログラム。同時視聴、ライブブロードキャスト、チャットなどの機能を提供します" + local docker_url="公式サイト紹介:https://github.com/synctv-org/synctv" + local docker_use="echo \"初期アカウントとパスワード: root。ログイン後、時間内にログイン パスワードを変更してください\"" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 88|owncast) + + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 + + docker_rum() { + + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest + + + } + + local docker_describe="オープンソース、無料の自社構築ライブ ブロードキャスト プラットフォーム" + local docker_url="公式サイト紹介:https://owncast.online" + local docker_use="echo \"管理者ページにアクセスするには、アクセス アドレスの後に /admin を続けます\"" + local docker_passwd="echo \"初期アカウント: admin 初期パスワード: abc123 ログイン後、時間内にログイン パスワードを変更してください\"" + local app_size="1" + docker_app + + ;; + + + + 89|file-code-box) + + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 + + docker_rum() { + + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest + + } + + local docker_describe="匿名のパスワードでテキストやファイルを共有し、速達のようにファイルを受け取ります" + local docker_url="公式サイト紹介:https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"管理者ページにアクセスするには、アクセス アドレスの後に /#/admin を続けます\"" + local docker_passwd="echo \"管理者パスワード: FileCodeBox2023\"" + local app_size="1" + docker_app + + ;; + - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + + + 90|matrix) + + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 + + docker_rum() { + + add_yuming + + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate fi - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - docker_rum() { + echo "初期ユーザーまたは管理者を作成します。以下のユーザー名とパスワード、および管理者であるかどうかを設定してください。" + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - } + docker restart matrix - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + } - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Matrix は分散型チャット プロトコルです" + local docker_url="公式サイト紹介:https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 41) + ;; - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } - panel_app_manage() { - panel-cli - } + 91|gitea) - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } + local app_id="91" - install_panel + local app_name="gitea プライベート コード リポジトリ" + local app_text="GitHub に近いエクスペリエンスを提供する、無料の新世代コード ホスティング プラットフォーム。" + local app_url="ビデオ紹介: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - ;; + docker_app_install() { + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - docker_rum() { - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - } - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "アプリがアンインストールされました" + } - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + docker_app_plus - docker_rum() { + ;; - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs - } - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + 92|filebrowser) - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - docker_rum() { + docker_rum() { - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - } + } - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Webベースのファイルマネージャーです" + local docker_url="公式サイト紹介:https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + ;; - docker_rum() { + 93|dufs) - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 - } + docker_rum() { - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 + } + + local docker_describe="シンプルな静的ファイル サーバー、アップロードとダウンロードをサポート" + local docker_url="公式サイト紹介:https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest + 94|gopeed) - } + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 47) + read -e -p "ログインユーザー名を設定します:" app_use + read -e -p "ログインパスワードを設定します:" app_passwd + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} + } - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + local docker_describe="複数のプロトコルをサポートする分散型高速ダウンロード ツール" + local docker_url="公式サイト紹介:https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_install() { - prometheus_install - clear - ip_address - echo "インストール" - check_docker_app_ip - echo "最初のユーザー名とパスワードは次のとおりです" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } + ;; - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - rm -rf /home/docker/monitoring - echo "アプリはアンインストールされています" - } - docker_app_plus - ;; + 95|paperless) - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 + local app_id="95" - docker_rum() { + local app_name="ペーパーレス文書管理プラットフォーム" + local app_text="オープンソースの電子文書管理システムであり、その主な目的は紙文書をデジタル化して管理することです。" + local app_url="ビデオ紹介: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + docker_app_install() { + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - } + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 - docker_rum() { + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true - } + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "アプリがアンインストールされました" + } - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_plus + ;; - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 - docker_rum() { - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest + 96|2fauth) - } + local app_id="96" - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_name="2FAuth セルフホスト型 2 段階認証システム" + local app_text="セルフホスト型の 2 要素認証 (2FA) アカウント管理および検証コード生成ツール。" + local app_url="公式サイト:https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" + docker_app_install() { + + add_yuming + + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth + + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml + + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 51) clear - send_stats "PVEチキン" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + echo "インストール完了" + check_docker_app_ip + } - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - docker_rum() { - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "アプリがアンインストールされました" + } - } + docker_app_plus - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + 97|wgs) - } + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_rum() { - 54) + read -e -p "ネットワーク内のクライアントの数を入力してください (デフォルトは 5):" COUNT + COUNT=${COUNT:-5} + read -e -p "WireGuard ネットワーク セグメントを入力してください (デフォルトは 10.13.13.0):" NETWORK + NETWORK=${NETWORK:-10.13.13.0} - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } + ip link delete wg0 &>/dev/null - panel_app_manage() { - panel_app_install - } + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - panel_app_uninstall() { - panel_app_install - } - install_panel - ;; + sleep 3 + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - 55) - frps_panel - ;; + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " - 56) - frpc_panel - ;; + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' - docker_rum() { + docker restart wireguard - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + sleep 2 + echo + echo -e "${gl_huang}すべてのクライアント QR コード構成:${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}すべてのクライアント構成コード:${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}各クライアントのすべての出力を構成します。利用方法は以下の通りです。${gl_bai}" + echo -e "${gl_lv}1. 携帯電話に wg APP をダウンロードし、上の QR コードをスキャンして、すぐにインターネットに接続します。${gl_bai}" + echo -e "${gl_lv}2. Windows 用クライアントをダウンロードし、ネットワークに接続するための構成コードをコピーします。${gl_bai}" + echo -e "${gl_lv}3. スクリプトを使用して Linux に WG クライアントを展開し、構成コードをコピーしてネットワークに接続します。${gl_bai}" + echo -e "${gl_lv}公式クライアントのダウンロード方法:https://www.wireguard.com/install/${gl_bai}" + break_end - } + } - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local docker_describe="最新の高性能仮想プライベート ネットワーク ツール" + local docker_url="公式サイト紹介:https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + 98|wgc) - docker compose up -d - clear - echo "インストール" - check_docker_app_ip - } + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } + docker_rum() { - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "アプリはアンインストールされています" - } + mkdir -p /home/docker/wireguard/config/ - docker_app_plus + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - ;; + # ディレクトリが存在しない場合は作成する + mkdir -p "$(dirname "$CONFIG_FILE")" - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + echo "クライアント構成を貼り付け、Enter キーを 2 回押して保存してください。" - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + # 変数を初期化する + input="" + empty_line_count=0 - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + # ユーザー入力を 1 行ずつ読み取ります + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done + # 設定ファイルの書き込み + echo "$input" > "$CONFIG_FILE" - docker compose up -d - clear - echo "インストール" - check_docker_app_ip - } + echo "クライアント設定の保存場所$CONFIG_FILE" - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + ip link delete wg0 &>/dev/null - docker compose up -d - clear - echo "インストール" - check_docker_app_ip + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - } + sleep 3 - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "アプリはアンインストールされています" - } + docker logs wireguardc - docker_app_plus + break_end - ;; + } + local docker_describe="最新の高性能仮想プライベート ネットワーク ツール" + local docker_url="公式サイト紹介:https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 60) + ;; - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "インストール" - check_docker_app_ip - echo "初期ユーザー名:admin" - echo "最初のパスワード:changeme" - } + 99|dsm) + local app_id="99" - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "アプリが更新されました" - } + local app_name="DSM Synology 仮想マシン" + local app_text="Dockerコンテナ内の仮想DSM" + local app_url="公式ウェブサイト:https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" + docker_app_install() { - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "アプリはアンインストールされています" - } + read -e -p "CPU コアの数を設定します (デフォルトは 2)。" CPU_CORES + local CPU_CORES=${CPU_CORES:-2} - docker_app_plus - ;; + read -e -p "メモリ サイズを設定します (デフォルトは 4G):" RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - docker_rum() { + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d + + clear + echo "インストール完了" + check_docker_app_ip + } - } - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "アプリがアンインストールされました" + } - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + docker_app_plus - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "インストール" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } + ;; - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "アプリはアンインストールされています" - } - docker_app_plus - ;; + 100|syncthing) + + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local docker_describe="オープンソースのピアツーピア ファイル同期ツール。Dropbox や Resilio Sync に似ていますが、完全に分散化されています。" + local docker_url="公式サイト紹介:https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main - } + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI動画生成ツール" + local app_text="MoneyPrinterTurbo は、AI ラージモデルを使用して高解像度のショートビデオを合成するツールです" + local app_url="公式ウェブサイト:https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "アプリがアンインストールされました" + } - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + docker_app_plus - docker_rum() { + ;; - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" - } + 102|vocechat) - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - 66) - yt_menu_pro - ;; + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + } - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local docker_describe="独自導入をサポートするパーソナルクラウドソーシャルメディアチャットサービスです。" + local docker_url="公式サイト紹介:https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + 103|umami) + local app_id="103" + local app_name="Umami ウェブサイト統計ツール" + local app_text="Google Analytics に似た、オープンソースの軽量でプライバシーに配慮した Web サイト分析ツール。" + local app_url="公式サイト:https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + echo "初期ユーザー名: admin" + echo "初期パスワード:umami" + } + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "アプリがアンインストールされました" + } - docker_rum() { + docker_app_plus - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo + ;; - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + 104|nginx-stream) + stream_panel + ;; - } - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 105|siyuan) + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 + docker_rum() { - docker_rum() { + read -e -p "ログインパスワードを設定します:" app_passwd - mkdir -p /home/docker/astrbot/data + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + } - } + local docker_describe="Siyuan Notes はプライバシーを最優先したナレッジ管理システムです" + local docker_url="公式サイト紹介:https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + 106|drawnix) - docker_rum() { + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_rum() { - } + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="これは、マインド マップ、フローチャートなどを統合する強力なオープンソース ホワイトボード ツールです。" + local docker_url="公式サイト紹介:https://github.com/plait-board/drawnix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { + 107|pansou) - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou は、高パフォーマンスのネットワーク ディスク リソース検索 API サービスです。" + local docker_url="公式サイト紹介:https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 73) - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 - docker_rum() { + 108|langbot) + local app_id="108" + local app_name="LangBot チャットボット" + local app_text="これは、オープンソースの大規模言語モデルのネイティブ インスタント メッセージング ロボット開発プラットフォームです。" + local app_url="公式ウェブサイト:https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - read -e -p "libretvログインパスワードを設定します。" app_passwd + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "アプリがアンインストールされました" + } - ;; + docker_app_plus + ;; - 74) - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + 109|zfile) - docker_rum() { + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - read -e -p "MOONTVログインパスワードを設定します。" app_passwd + docker_rum() { - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest - } + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="これは、個人または小規模チームに適したオンライン ネットワーク ディスク プログラムです。" + local docker_url="公式サイト紹介:https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 75) + ;; - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 - docker_rum() { + 110|karakeep) + local app_id="110" + local app_name="karakeepのブックマーク管理" + local app_text="は、データ蓄積者向けに設計された人工知能機能を備えた自己ホスト型ブックマーク アプリです。" + local app_url="公式サイト:https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + docker compose up -d + clear + echo "インストール完了" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "アプリがアンインストールされました" + } + docker_app_plus - ;; + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 + 111|convertx) - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - } + docker_rum() { - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} + } - ;; + local docker_describe="これは、強力なマルチフォーマット ファイル変換ツール (ドキュメント、画像、オーディオ、ビデオなどをサポート) です。ドメイン名アクセスを追加することを強くお勧めします。" + local docker_url="プロジェクトアドレス: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - 77) + ;; - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 - docker_rum() { + 112|lucky) - read -e -p "設定${docker_name}ログインユーザー名:" app_use - read -e -p "設定${docker_name}ログインパスワード:" app_passwd + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # Lucky はホスト ネットワーク モードを使用するため、ここでのポートは記録と説明の参照のみを目的としており、実際にはアプリケーション自体によって制御されます (デフォルトは 16601)。 + local docker_port=8112 - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + docker_rum() { - } + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + echo "Lucky が初期化されるのを待っています..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - ;; + } + local docker_describe="Lucky は、DDNS、リバース プロキシ、WOL、その他の機能をサポートする大規模なイントラネット ペネトレーションおよびポート フォワーディング管理ツールです。" + local docker_url="プロジェクトアドレス: https://github.com/gdy666/lucky" + local docker_use="echo \"デフォルトのアカウントパスワード: 666\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 78) - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + 113|firefox) - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 - docker_app_update() { - docker_app_install - } + docker_rum() { + read -e -p "ログインパスワードを設定します:" admin_password - docker_app_uninstall() { - docker_app_install - } + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - docker_app_plus - ;; + local docker_describe="これは、Web ページを介したデスクトップ ブラウザ インターフェイスへの直接アクセスをサポートする、Docker で実行される Firefox ブラウザです。" + local docker_url="プロジェクトアドレス: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 79) + b) + clear + send_stats "すべてのアプリケーションのバックアップ" - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}バックアップ中$backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_rum() { + while true; do + clear + echo "バックアップファイルが作成されました: /$backup_filename" + read -e -p "バックアップ データをリモート サーバーに転送しますか? (はい/いいえ):" choice + case "$choice" in + [Yy]) + read -e -p "リモートサーバーのIPを入力してください:" remote_ip + read -e -p "ターゲット サーバーの SSH ポート [デフォルト 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel + if [ -z "$remote_ip" ]; then + echo "エラー: リモート サーバーの IP を入力してください。" + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "ファイルはリモート サーバー/ルート ディレクトリに転送されます。" + else + echo "転送するファイルが見つかりませんでした。" + fi + break + ;; + *) + echo "注: 現在のバックアップには Docker プロジェクトのみが含まれており、Pagoda や 1panel などの Web サイト構築パネルのデータ バックアップは含まれていません。" + break + ;; + esac + done - } + ;; - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + r) + root_use + send_stats "すべてのアプリを復元する" + echo "利用可能なアプリケーションのバックアップ" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "Enter キーを押して最新のバックアップを復元し、バックアップ ファイル名を入力して指定したバックアップを復元し、0 を入力して終了します。" filename - ;; + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # ユーザーがファイル名を入力しない場合は、最新の圧縮パッケージが使用されます。 + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}解凍中$filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "アプリケーションデータが復元されました。現在、アプリケーションを復元するには、手動で指定されたアプリケーションメニューに入り、アプリケーションを更新してください。" + else + echo "圧縮パッケージが見つかりませんでした。" + fi + ;; - 0) - kejilion - ;; - *) - echo "無効な入力!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}エラー: 番号が見つかりません${sub_choice}アプリケーション構成${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do clear send_stats "バックエンドワークスペース" echo -e "バックエンドワークスペース" - echo -e "このシステムは、バックエンドで実行できるワークスペースを提供し、長期タスクを実行するために使用できます。" - echo -e "SSHを切断したとしても、ワークスペースのタスクは中断されず、バックグラウンドのタスクが居住します。" - echo -e "${gl_huang}ヒント:${gl_bai}ワークスペースに入った後、Ctrl+Bを使用してDを押してワークスペースを終了します!" + echo -e "システムは、バックグラウンドで永続的に実行できるワークスペースを提供し、長期的なタスクを実行するために使用できます。" + echo -e "SSH を切断しても、ワークスペース内のタスクは中断されず、タスクはバックグラウンドで残ります。" + echo -e "${gl_huang}ヒント:${gl_bai}ワークスペースに入ったら、Ctrl+b を使用し、次に d を単独で押してワークスペースを終了します。" echo -e "${gl_kjlan}------------------------" - echo "現在既存のワークスペースのリスト" + echo "現在存在するワークスペースのリスト" echo -e "${gl_kjlan}------------------------" tmux list-sessions echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}ワークスペース番号1" - echo -e "${gl_kjlan}2. ${gl_bai}ワークスペースNo. 2" - echo -e "${gl_kjlan}3. ${gl_bai}ワークスペース番号3" - echo -e "${gl_kjlan}4. ${gl_bai}ワークスペースNo. 4" - echo -e "${gl_kjlan}5. ${gl_bai}ワークスペースNo. 5" - echo -e "${gl_kjlan}6. ${gl_bai}ワークスペースNo. 6" - echo -e "${gl_kjlan}7. ${gl_bai}ワークスペースNo. 7" - echo -e "${gl_kjlan}8. ${gl_bai}ワークスペースNo. 8" - echo -e "${gl_kjlan}9. ${gl_bai}ワークスペースNo. 9" - echo -e "${gl_kjlan}10. ${gl_bai}ワークスペースNo. 10" + echo -e "${gl_kjlan}1. ${gl_bai}作業エリア1" + echo -e "${gl_kjlan}2. ${gl_bai}作業エリア 2" + echo -e "${gl_kjlan}3. ${gl_bai}作業エリア 3" + echo -e "${gl_kjlan}4. ${gl_bai}作業エリア 4" + echo -e "${gl_kjlan}5. ${gl_bai}ワークスペースNo.5" + echo -e "${gl_kjlan}6. ${gl_bai}作業エリア6" + echo -e "${gl_kjlan}7. ${gl_bai}作業エリア 7" + echo -e "${gl_kjlan}8. ${gl_bai}作業エリア8" + echo -e "${gl_kjlan}9. ${gl_bai}ワークスペースNo.9" + echo -e "${gl_kjlan}10. ${gl_bai}ワークスペース10" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}SSH常駐モード${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}22. ${gl_bai}ワークスペースを作成/入力します" - echo -e "${gl_kjlan}23. ${gl_bai}バックグラウンドワークスペースにコマンドを注入します" - echo -e "${gl_kjlan}24. ${gl_bai}指定されたワークスペースを削除します" + echo -e "${gl_kjlan}22. ${gl_bai}ワークスペースの作成/入力" + echo -e "${gl_kjlan}23. ${gl_bai}バックグラウンドワークスペースにコマンドを挿入する" + echo -e "${gl_kjlan}24. ${gl_bai}指定したワークスペースを削除します" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in @@ -10676,7 +13165,7 @@ linux_work() { clear install tmux local SESSION_NAME="work1" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; @@ -10684,63 +13173,63 @@ linux_work() { clear install tmux local SESSION_NAME="work2" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 3) clear install tmux local SESSION_NAME="work3" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 4) clear install tmux local SESSION_NAME="work4" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 5) clear install tmux local SESSION_NAME="work5" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 6) clear install tmux local SESSION_NAME="work6" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 7) clear install tmux local SESSION_NAME="work7" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 8) clear install tmux local SESSION_NAME="work8" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 9) clear install tmux local SESSION_NAME="work9" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; 10) clear install tmux local SESSION_NAME="work10" - send_stats "ワークスペースを開始します$SESSION_NAME" + send_stats "ワークスペースの開始$SESSION_NAME" tmux_run ;; @@ -10748,30 +13237,30 @@ linux_work() { while true; do clear if grep -q 'tmux attach-session -t sshd || tmux new-session -s sshd' ~/.bashrc; then - local tmux_sshd_status="${gl_lv}开启${gl_bai}" + local tmux_sshd_status="${gl_lv}オンにする${gl_bai}" else - local tmux_sshd_status="${gl_hui}关闭${gl_bai}" + local tmux_sshd_status="${gl_hui}閉鎖${gl_bai}" fi send_stats "SSH常駐モード" echo -e "SSH常駐モード${tmux_sshd_status}" - echo "SSH接続が有効になった後、レジデントモードに直接入力し、以前の作業状態に戻ります。" + echo "SSH 接続を開いた後、直接常駐モードに入り、前の動作状態に直接戻ります。" echo "------------------------" - echo "1。2をオンにします。オフにします" + echo "1. オン 2. オフ" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" gongzuoqu_del + read -e -p "選択肢を入力してください:" gongzuoqu_del case "$gongzuoqu_del" in 1) install tmux local SESSION_NAME="sshd" - send_stats "ワークスペースを開始します$SESSION_NAME" - grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\ n#tmuxセッション\ nif [[-z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc + send_stats "ワークスペースの開始$SESSION_NAME" + grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\n# 自動的に tmux セッションに入ります\nif [[ -z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc source ~/.bashrc tmux_run ;; 2) - sed -i '/# 自动进入 tmux 会话/,+4d' ~/.bashrc + sed -i '/# 自動的に tmux セッションに入ります/,+4d' ~/.bashrc tmux kill-window -t sshd ;; *) @@ -10782,29 +13271,29 @@ linux_work() { ;; 22) - read -e -p "1001 KJ001 Work1など、作成または入力したワークスペースの名前を入力してください。" SESSION_NAME + read -e -p "作成または入力したワークスペースの名前を入力してください (1001 kj001 work1 など)。" SESSION_NAME tmux_run send_stats "カスタムワークスペース" ;; 23) - read -e -p "次のようなバックグラウンドで実行するコマンドを入力してください:curl -fssl https://get.docker.com SH:" tmuxd + read -e -p "バックグラウンドで実行するコマンドを入力してください。たとえば、curl -fsSL https://get.docker.com |し:" tmuxd tmux_run_d - send_stats "バックグラウンドワークスペースにコマンドを注入します" + send_stats "バックグラウンドワークスペースにコマンドを挿入する" ;; 24) - read -e -p "削除するワークスペースの名前を入力してください:" gongzuoqu_name + read -e -p "削除するワークスペースの名前を入力してください:" gongzuoqu_name tmux kill-window -t $gongzuoqu_name - send_stats "ワークスペースを削除します" + send_stats "ワークスペースの削除" ;; 0) kejilion ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -10823,59 +13312,155 @@ linux_work() { +# インテリジェントスイッチングミラーソース機能 +switch_mirror() { + # オプションのパラメータ、デフォルトは false + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # ユーザーの国を取得する + local country + country=$(curl -s ipinfo.io/country) + + echo "検出された国:$country" + + if [ "$country" = "CN" ]; then + echo "国内のミラーソースを使用..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "公式ミラーソースを使用してください..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "SSH防御" + while true; do + + check_f2b_status + echo -e "SSH防御プログラム$check_f2b_status" + echo "failed2ban はブルート フォース クラッキングを防ぐ SSH ツールです" + echo "公式サイト紹介:${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. 防御プログラムをインストールする" + echo "------------------------" + echo "2. SSH インターセプト記録の表示" + echo "3. リアルタイムログ監視" + echo "------------------------" + echo "9. 防御プログラムをアンインストールする" + echo "------------------------" + echo "0. 前のメニューに戻る" + echo "------------------------" + read -e -p "選択肢を入力してください:" sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban 防御プログラムがアンインストールされました" + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { while true; do clear - # send_stats「システムツール」 + # send_stats 「システムツール」 echo -e "システムツール" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}スクリプトの起動ショートカットキーを設定します${gl_kjlan}2. ${gl_bai}ログインパスワードを変更します" - echo -e "${gl_kjlan}3. ${gl_bai}ルートパスワードログインモード${gl_kjlan}4. ${gl_bai}指定されたバージョンのPythonをインストールします" - echo -e "${gl_kjlan}5. ${gl_bai}すべてのポートを開きます${gl_kjlan}6. ${gl_bai}SSH接続ポートを変更します" - echo -e "${gl_kjlan}7. ${gl_bai}DNSアドレスを最適化します${gl_kjlan}8. ${gl_bai}ワンクリック再インストールシステム${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}9. ${gl_bai}ルートアカウントを無効にして新しいアカウントを作成します${gl_kjlan}10. ${gl_bai}優先順位IPv4/IPv6を切り替えます" + echo -e "${gl_kjlan}1. ${gl_bai}スクリプト起動のショートカットキーを設定する${gl_kjlan}2. ${gl_bai}ログインパスワードを変更する" + echo -e "${gl_kjlan}3. ${gl_bai}ROOTパスワードログインモード${gl_kjlan}4. ${gl_bai}指定されたバージョンの Python をインストールします" + echo -e "${gl_kjlan}5. ${gl_bai}すべてのポートを開く${gl_kjlan}6. ${gl_bai}SSH接続ポートの変更" + echo -e "${gl_kjlan}7. ${gl_bai}DNSアドレスを最適化する${gl_kjlan}8. ${gl_bai}ワンクリックでシステムを再インストールします${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}9. ${gl_bai}ROOTアカウントを無効にして新しいアカウントを作成する${gl_kjlan}10. ${gl_bai}スイッチ優先度 ipv4/ipv6" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}ポートの職業ステータスを確認してください${gl_kjlan}12. ${gl_bai}仮想メモリサイズを変更します" - echo -e "${gl_kjlan}13. ${gl_bai}ユーザー管理${gl_kjlan}14. ${gl_bai}ユーザー/パスワードジェネレーター" - echo -e "${gl_kjlan}15. ${gl_bai}システムタイムゾーンの調整${gl_kjlan}16. ${gl_bai}BBR3加速度をセットアップします" - echo -e "${gl_kjlan}17. ${gl_bai}ファイアウォール上級マネージャー${gl_kjlan}18. ${gl_bai}ホスト名を変更します" - echo -e "${gl_kjlan}19. ${gl_bai}システムの更新ソースを切り替えます${gl_kjlan}20. ${gl_bai}タイミングタスク管理" + echo -e "${gl_kjlan}11. ${gl_bai}ポートの占有状況を確認する${gl_kjlan}12. ${gl_bai}仮想メモリのサイズを変更する" + echo -e "${gl_kjlan}13. ${gl_bai}ユーザー管理${gl_kjlan}14. ${gl_bai}ユーザー/パスワード生成器" + echo -e "${gl_kjlan}15. ${gl_bai}システムのタイムゾーン調整${gl_kjlan}16. ${gl_bai}BBR3アクセラレーションの設定" + echo -e "${gl_kjlan}17. ${gl_bai}ファイアウォール アドバンスト マネージャー${gl_kjlan}18. ${gl_bai}ホスト名の変更" + echo -e "${gl_kjlan}19. ${gl_bai}システムアップデート元の切り替え${gl_kjlan}20. ${gl_bai}スケジュールされたタスクの管理" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}ネイティブホストの解析${gl_kjlan}22. ${gl_bai}SSH防衛プログラム" - echo -e "${gl_kjlan}23. ${gl_bai}電流制限の自動シャットダウン${gl_kjlan}24. ${gl_bai}ルート秘密キーログインモード" - echo -e "${gl_kjlan}25. ${gl_bai}TGボットシステムの監視と早期警告${gl_kjlan}26. ${gl_bai}opensshの高リスクの脆弱性(xiuyuan)を修正" - echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linuxカーネルのアップグレード${gl_kjlan}28. ${gl_bai}Linuxシステムにおけるカーネルパラメーターの最適化${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}21. ${gl_bai}ネイティブホスト解像度${gl_kjlan}22. ${gl_bai}SSH防御プログラム" + echo -e "${gl_kjlan}23. ${gl_bai}電流制限自動シャットダウン${gl_kjlan}24. ${gl_bai}ROOT秘密鍵ログインモード" + echo -e "${gl_kjlan}25. ${gl_bai}TG-bot システムの監視と早期警告${gl_kjlan}26. ${gl_bai}OpenSSH の高リスク脆弱性を修正" + echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linux カーネルのアップグレード${gl_kjlan}28. ${gl_bai}Linuxシステムのカーネルパラメータの最適化${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}29. ${gl_bai}ウイルススキャンツール${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}ファイルマネージャー" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}システム言語を切り替えます${gl_kjlan}32. ${gl_bai}コマンドラインの美化ツール${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}システムリサイクルビンをセットアップします${gl_kjlan}34. ${gl_bai}システムのバックアップと回復" + echo -e "${gl_kjlan}31. ${gl_bai}システム言語を切り替える${gl_kjlan}32. ${gl_bai}コマンドライン美化ツール${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}システムのごみ箱をセットアップする${gl_kjlan}34. ${gl_bai}システムのバックアップとリカバリ" echo -e "${gl_kjlan}35. ${gl_bai}SSHリモート接続ツール${gl_kjlan}36. ${gl_bai}ハードディスクパーティション管理ツール" - echo -e "${gl_kjlan}37. ${gl_bai}コマンドラインの履歴${gl_kjlan}38. ${gl_bai}RSYNCリモート同期ツール" + echo -e "${gl_kjlan}37. ${gl_bai}コマンドラインの履歴${gl_kjlan}38. ${gl_bai}rsync リモート同期ツール" + echo -e "${gl_kjlan}39. ${gl_bai}コマンドのお気に入り${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}メッセージボード${gl_kjlan}66. ${gl_bai}ワンストップシステムの最適化${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}41. ${gl_bai}掲示板${gl_kjlan}66. ${gl_bai}ワンストップのシステムチューニング${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}99. ${gl_bai}サーバーを再起動します${gl_kjlan}100. ${gl_bai}プライバシーとセキュリティ" - echo -e "${gl_kjlan}101. ${gl_bai}Kコマンドの高度な使用${gl_huang}★${gl_bai} ${gl_kjlan}102. ${gl_bai}テックライオンスクリプトをアンインストールします" + echo -e "${gl_kjlan}101. ${gl_bai}k コマンドの高度な使用法${gl_huang}★${gl_bai} ${gl_kjlan}102. ${gl_bai}Tech Lion スクリプトをアンインストールする" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻ります" + echo -e "${gl_kjlan}0. ${gl_bai}メインメニューに戻る" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) while true; do clear - read -e -p "ショートカットキーを入力してください(出口に0を入力してください):" kuaijiejian + read -e -p "ショートカット キーを入力してください (終了するには 0 を入力してください):" kuaijiejian if [ "$kuaijiejian" == "0" ]; then break_end linux_Settings fi find /usr/local/bin/ -type l -exec bash -c 'test "$(readlink -f {})" = "/usr/local/bin/k" && rm -f {}' \; ln -s /usr/local/bin/k /usr/local/bin/$kuaijiejian - echo "ショートカットキーが設定されています" - send_stats "スクリプトのショートカットキーが設定されています" + echo "ショートカットキーが設定されている" + send_stats "スクリプトのショートカットキーが設定されました" break_end linux_Settings done @@ -10883,34 +13468,34 @@ linux_Settings() { 2) clear - send_stats "ログインパスワードを設定します" - echo "ログインパスワードを設定します" + send_stats "ログインパスワードを設定する" + echo "ログインパスワードを設定する" passwd ;; 3) root_use - send_stats "ルートパスワードモード" + send_stats "rootパスワードモード" add_sshpasswd ;; 4) root_use - send_stats "Pyバージョン管理" - echo "Pythonバージョン管理" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1pm42157ck?t=0.1" + send_stats "pyのバージョン管理" + echo "Pythonのバージョン管理" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1Pm42157cK?t=0.1" echo "---------------------------------------" - echo "この機能は、Pythonが正式にサポートするバージョンをシームレスにインストールします!" + echo "この機能を使用すると、Python で公式にサポートされているバージョンをシームレスにインストールできます。" local VERSION=$(python3 -V 2>&1 | awk '{print $2}') - echo -e "現在のPythonバージョン番号:${gl_huang}$VERSION${gl_bai}" + echo -e "現在のPythonのバージョン番号:${gl_huang}$VERSION${gl_bai}" echo "------------" - echo "推奨バージョン:3.12 3.11 3.10 3.9 3.8 2.7" - echo "クエリの詳細:https://www.python.org/downloads/" + echo "推奨バージョン: 3.12 3.11 3.10 3.9 3.8 2.7" + echo "他のバージョンを確認してください: https://www.python.org/downloads/" echo "------------" - read -e -p "インストールするPythonバージョン番号を入力します(Enter 0からExit):" py_new_v + read -e -p "インストールする Python のバージョン番号を入力します (終了するには 0 を入力します)。" py_new_v if [[ "$py_new_v" == "0" ]]; then - send_stats "スクリプトPy管理" + send_stats "スクリプト PY 管理" break_end linux_Settings fi @@ -10943,7 +13528,7 @@ linux_Settings() { apk update && apk add git apk add --no-cache bash gcc musl-dev libffi-dev openssl-dev bzip2-dev zlib-dev readline-dev sqlite-dev libc6-compat linux-headers make xz-dev build-base ncurses-dev else - echo "不明なパッケージマネージャー!" + echo "不明なパッケージマネージャーです!" return fi @@ -10972,14 +13557,14 @@ EOF rm -rf $(pyenv root)/cache/* local VERSION=$(python -V 2>&1 | awk '{print $2}') - echo -e "現在のPythonバージョン番号:${gl_huang}$VERSION${gl_bai}" - send_stats "スイッチスクリプトPyバージョン" + echo -e "現在のPythonのバージョン番号:${gl_huang}$VERSION${gl_bai}" + send_stats "スクリプトPYバージョン切り替え" ;; 5) root_use - send_stats "オープンポート" + send_stats "ポートを開く" iptables_open remove iptables-persistent ufw firewalld iptables-services > /dev/null 2>&1 echo "すべてのポートが開いています" @@ -10987,40 +13572,40 @@ EOF ;; 6) root_use - send_stats "SSHポートを変更します" + send_stats "SSHポートを変更する" while true; do clear sed -i 's/#Port/Port/' /etc/ssh/sshd_config - # 現在のSSHポート番号をお読みください + # 現在の SSH ポート番号を読み取ります local current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') - # 現在のSSHポート番号を印刷します - echo -e "現在のSSHポート番号は次のとおりです。${gl_huang}$current_port ${gl_bai}" + # 現在の SSH ポート番号を出力する + echo -e "現在の SSH ポート番号は次のとおりです。${gl_huang}$current_port ${gl_bai}" echo "------------------------" - echo "ポート番号が1〜65535の範囲の数字(0を入力して終了)" + echo "ポート番号の範囲は 1 ~ 65535 です (終了するには 0 を入力します)。" - # ユーザーに新しいSSHポート番号を入力するように促します - read -e -p "新しいSSHポート番号を入力してください:" new_port + # 新しい SSH ポート番号の入力をユーザーに求める + read -e -p "新しい SSH ポート番号を入力してください:" new_port - # ポート番号が有効な範囲内にあるかどうかを判断します + # ポート番号が有効な範囲内であるかどうかを確認します。 if [[ $new_port =~ ^[0-9]+$ ]]; then # 检查输入是否为数字 if [[ $new_port -ge 1 && $new_port -le 65535 ]]; then send_stats "SSHポートが変更されました" new_ssh_port elif [[ $new_port -eq 0 ]]; then - send_stats "SSHポート変更を終了します" + send_stats "SSHポート変更の終了" break else - echo "ポート番号は無効です。1〜65535の数字を入力してください。" - send_stats "無効なSSHポート入力" + echo "ポート番号が無効です。 1 ~ 65535 の数字を入力してください。" + send_stats "無効な SSH ポートが入力されました" break_end fi else - echo "入力が無効です。番号を入力してください。" - send_stats "無効なSSHポート入力" + echo "入力が無効です。数値を入力してください。" + send_stats "無効な SSH ポートが入力されました" break_end fi done @@ -11039,8 +13624,8 @@ EOF ;; 9) root_use - send_stats "新しいユーザーはルートを無効にします" - read -e -p "新しいユーザー名を入力してください(出口に0を入力してください):" new_username + send_stats "新規ユーザーの root を無効にする" + read -e -p "新しいユーザー名を入力してください (終了するには 0 を入力してください):" new_username if [ "$new_username" == "0" ]; then break_end linux_Settings @@ -11049,53 +13634,54 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root - echo "操作が完了しました。" + echo "操作は完了です。" ;; 10) root_use - send_stats "V4/V6の優先度を設定します" + send_stats "v4/v6 の優先順位を設定する" while true; do clear - echo "V4/V6の優先度を設定します" + echo "v4/v6 の優先順位を設定する" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then - echo -e "現在のネットワーク優先設定:${gl_huang}IPv4${gl_bai}優先度" + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then + echo -e "現在のネットワーク優先設定:${gl_huang}IPv4${gl_bai}優先度" else - echo -e "現在のネットワーク優先設定:${gl_huang}IPv6${gl_bai}優先度" + echo -e "現在のネットワーク優先設定:${gl_huang}IPv6${gl_bai}優先度" fi + echo "" echo "------------------------" - echo "1。IPv4優先度2。IPv6優先度3。IPv6修理ツール" + echo "1. IPv4 が先 2. IPv6 が先 3. IPv6 修復ツール" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "優先ネットワークを選択します。" choice + read -e -p "優先ネットワークを選択してください:" choice case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "IPv4の優先度に切り替えました" - send_stats "IPv4の優先度に切り替えました" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 - echo "IPv6の優先度に切り替えました" - send_stats "IPv6の優先度に切り替えました" + rm -f /etc/gai.conf + echo "最初にIPv6に切り替えました" + send_stats "最初にIPv6に切り替えました" ;; 3) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "この関数は、彼のおかげで、マスターJHBによって提供されます!" - send_stats "IPv6修正" + echo "この機能は jhb によって提供されています。ありがとう!" + send_stats "IPv6修復" ;; *) @@ -11113,43 +13699,43 @@ EOF 12) root_use - send_stats "仮想メモリを設定します" + send_stats "仮想メモリを設定する" while true; do clear - echo "仮想メモリを設定します" + echo "仮想メモリを設定する" local swap_used=$(free -m | awk 'NR==3{print $3}') local swap_total=$(free -m | awk 'NR==3{print $2}') local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - echo -e "現在の仮想メモリ:${gl_huang}$swap_info${gl_bai}" + echo -e "現在の仮想メモリ:${gl_huang}$swap_info${gl_bai}" echo "------------------------" - echo "1。1024Mの割り当て2。2048m3を割り当てます。4096m4。カスタムサイズを割り当てます" + echo "1. 1024M の割り当て 2. 2048M の割り当て 3. 4096M の割り当て 4. カスタム サイズ" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" choice + read -e -p "選択肢を入力してください:" choice case "$choice" in 1) - send_stats "1G仮想メモリが設定されています" + send_stats "1Gの仮想メモリが設定されています" add_swap 1024 ;; 2) - send_stats "2G仮想メモリが設定されています" + send_stats "2Gの仮想メモリが設定されています" add_swap 2048 ;; 3) - send_stats "4G仮想メモリが設定されています" + send_stats "4G仮想メモリが設定されました" add_swap 4096 ;; 4) - read -e -p "仮想メモリサイズ(ユニットM)を入力してください:" new_swap + read -e -p "仮想メモリ サイズ (単位 M) を入力してください:" new_swap add_swap "$new_swap" - send_stats "カスタム仮想メモリが設定されています" + send_stats "カスタム仮想メモリセット" ;; *) @@ -11165,7 +13751,7 @@ EOF send_stats "ユーザー管理" echo "ユーザーリスト" echo "----------------------------------------------------------------------------" - printf "%-24s %-34s %-20s %-10s\n" "用户名" "用户权限" "用户组" "sudo权限" + printf "%-24s %-34s %-20s %-10s\n" "ユーザー名" "ユーザー権限" "ユーザーグループ" "sudo 権限" while IFS=: read -r username _ userid groupid _ _ homedir shell; do local groups=$(groups "$username" | cut -d : -f 2) local sudo_status=$(sudo -n -lU "$username" 2>/dev/null | grep -q '(ALL : ALL)' && echo "Yes" || echo "No") @@ -11176,56 +13762,60 @@ EOF echo "" echo "アカウント操作" echo "------------------------" - echo "1.通常のアカウントを作成する2。プレミアムアカウントを作成します" + echo "1. 通常アカウントを作成する 2. プレミアムアカウントを作成する" echo "------------------------" - echo "3.最高の権限を与える4。最高の権限をキャンセルします" + echo "3. 最高の権限を付与する 4. 最高の権限を削除する" echo "------------------------" - echo "5.アカウントを削除します" + echo "5. アカウントを削除する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - # ユーザーに新しいユーザー名を入力するように求めます - read -e -p "新しいユーザー名を入力してください:" new_username + # ユーザーに新しいユーザー名の入力を求める + read -e -p "新しいユーザー名を入力してください:" new_username - # 新しいユーザーを作成し、パスワードを設定します + # 新しいユーザーを作成してパスワードを設定する useradd -m -s /bin/bash "$new_username" passwd "$new_username" - echo "操作が完了しました。" + echo "操作は完了です。" ;; 2) - # ユーザーに新しいユーザー名を入力するように求めます - read -e -p "新しいユーザー名を入力してください:" new_username + # ユーザーに新しいユーザー名の入力を求める + read -e -p "新しいユーザー名を入力してください:" new_username - # 新しいユーザーを作成し、パスワードを設定します + # 新しいユーザーを作成してパスワードを設定する useradd -m -s /bin/bash "$new_username" passwd "$new_username" - # 新規ユーザーのsudo許可を付与します + # 新しいユーザーに sudo 権限を付与します echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers - echo "操作が完了しました。" + install sudo + + echo "操作は完了です。" ;; 3) - read -e -p "ユーザー名を入力してください:" username - # 新規ユーザーのsudo許可を付与します + read -e -p "ユーザー名を入力してください:" username + # 新しいユーザーに sudo 権限を付与します echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) - read -e -p "ユーザー名を入力してください:" username - # sudoersファイルからユーザーのsudoアクセス許可を削除します + read -e -p "ユーザー名を入力してください:" username + # sudoers ファイルからユーザーの sudo 権限を削除する sed -i "/^$username\sALL=(ALL:ALL)\sALL/d" /etc/sudoers ;; 5) - read -e -p "削除するにはユーザー名を入力してください:" username - # ユーザーとそのホームディレクトリを削除します + read -e -p "削除するユーザー名を入力してください:" username + # ユーザーとそのホームディレクトリを削除する userdel -r "$username" ;; @@ -11238,21 +13828,21 @@ EOF 14) clear - send_stats "ユーザー情報ジェネレーター" - echo "ランダムユーザー名" + send_stats "ユーザー情報ジェネレータ" + echo "ランダムなユーザー名" echo "------------------------" for i in {1..5}; do username="user$(< /dev/urandom tr -dc _a-z0-9 | head -c6)" - echo "ランダムユーザー名$i: $username" + echo "ランダムなユーザー名$i: $username" done echo "" - echo "ランダム名" + echo "ランダムな名前" echo "------------------------" local first_names=("John" "Jane" "Michael" "Emily" "David" "Sophia" "William" "Olivia" "James" "Emma" "Ava" "Liam" "Mia" "Noah" "Isabella") local last_names=("Smith" "Johnson" "Brown" "Davis" "Wilson" "Miller" "Jones" "Garcia" "Martinez" "Williams" "Lee" "Gonzalez" "Rodriguez" "Hernandez") - # 5つのランダムユーザー名を生成します + # 5 つのランダムなユーザー名を生成する for i in {1..5}; do local first_name_index=$((RANDOM % ${#first_names[@]})) local last_name_index=$((RANDOM % ${#last_names[@]})) @@ -11261,15 +13851,15 @@ EOF done echo "" - echo "ランダムuuid" + echo "ランダムな UUID" echo "------------------------" for i in {1..5}; do uuid=$(cat /proc/sys/kernel/random/uuid) - echo "ランダムuuid$i: $uuid" + echo "ランダムな UUID$i: $uuid" done echo "" - echo "16ビットランダムパスワード" + echo "16桁のランダムなパスワード" echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) @@ -11277,7 +13867,7 @@ EOF done echo "" - echo "32ビットランダムパスワード" + echo "32ビットのランダムなパスワード" echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32) @@ -11289,46 +13879,46 @@ EOF 15) root_use - send_stats "タイムゾーンを変更します" + send_stats "タイムゾーンを変更する" while true; do clear - echo "システム時間情報" + echo "システム時刻情報" - # 現在のシステムタイムゾーンを取得します + # 現在のシステムのタイムゾーンを取得する local timezone=$(current_timezone) - # 現在のシステム時間を取得します + # 現在のシステム時刻を取得する local current_time=$(date +"%Y-%m-%d %H:%M:%S") - # タイムゾーンと時間を表示します - echo "現在のシステムタイムゾーン:$timezone" - echo "現在のシステム時間:$current_time" + # タイムゾーンと時間を表示する + echo "現在のシステムのタイムゾーン:$timezone" + echo "現在のシステム時間:$current_time" echo "" - echo "タイムゾーンの切り替え" + echo "タイムゾーンスイッチ" echo "------------------------" echo "アジア" - echo "1。中国の上海時間2。中国の香港時間" - echo "3。日本の東京時間4。韓国のソウル時間" - echo "5。シンガポール時間6。インドのコルカタ時間" - echo "7。アラブ首長国連邦のドバイ時間8。オーストラリアのシドニー時間" - echo "9。タイのバンコクでの時間" + echo "1. 中国上海時間 2. 中国香港時間" + echo "3. 東京、日本時間 4. ソウル、韓国時間" + echo "5. シンガポール時間 6. インド、コルカタ時間" + echo "7. アラブ首長国連邦、ドバイ時間 8. オーストラリア、シドニー時間" + echo "9. タイ・バンコク時間" echo "------------------------" echo "ヨーロッパ" - echo "11。英国のロンドン時間12。パリの時間フランスの時間" - echo "13。ベルリン時代、ドイツ14。モスクワ・タイム、ロシア" - echo "15。オランダのユトレヒト時間16。スペインでのマドリード時間" + echo "11. ロンドン、イギリス時間 12. パリ、フランス時間" + echo "13. ベルリン、ドイツ時間 14. モスクワ、ロシア時間" + echo "15. ユトラハト時間、オランダ 16. マドリッド時間、スペイン" echo "------------------------" echo "アメリカ" - echo "21。WesternTime22。東部時間" - echo "23。カナダ時間24。メキシコの時間" - echo "25。ブラジル時間26。アルゼンチン時間" + echo "21. 米国西部時間 22. 米国東部時間" + echo "23. カナダ時間 24. メキシコ時間" + echo "25. ブラジル時間 26. アルゼンチン時間" echo "------------------------" - echo "31。UTCグローバル標準時間" + echo "31. UTC 世界標準時" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in @@ -11371,21 +13961,21 @@ EOF 18) root_use - send_stats "ホスト名を変更します" + send_stats "ホスト名の変更" while true; do clear local current_hostname=$(uname -n) - echo -e "現在のホスト名:${gl_huang}$current_hostname${gl_bai}" + echo -e "現在のホスト名:${gl_huang}$current_hostname${gl_bai}" echo "------------------------" - read -e -p "新しいホスト名を入力してください(出口に0を入力してください):" new_hostname + read -e -p "新しいホスト名を入力してください (終了するには 0 を入力してください):" new_hostname if [ -n "$new_hostname" ] && [ "$new_hostname" != "0" ]; then if [ -f /etc/alpine-release ]; then # Alpine echo "$new_hostname" > /etc/hostname hostname "$new_hostname" else - # Debian、Ubuntu、Centosなどの他のシステム。 + # Debian、Ubuntu、CentOS などのその他のシステム hostnamectl set-hostname "$new_hostname" sed -i "s/$current_hostname/$new_hostname/g" /etc/hostname systemctl restart systemd-hostnamed @@ -11403,11 +13993,11 @@ EOF echo "::1 $new_hostname localhost localhost.localdomain ipv6-localhost ipv6-loopback" >> /etc/hosts fi - echo "ホスト名は次のように変更されています。$new_hostname" + echo "ホスト名は次のように変更されました。$new_hostname" send_stats "ホスト名が変更されました" sleep 1 else - echo "終了すると、ホスト名は変更されていません。" + echo "ホスト名を変更せずに終了しました。" break fi done @@ -11415,20 +14005,20 @@ EOF 19) root_use - send_stats "システムの更新ソースを変更します" + send_stats "システムアップデートソースを変更する" clear - echo "更新ソース領域を選択します" - echo "LinuxMirrorsに接続して、システム更新ソースを切り替えます" + echo "更新元リージョンの選択" + echo "LinuxMirror にアクセスしてシステム アップデート ソースを切り替える" echo "------------------------" - echo "1。中国本土[デフォルト]2。中国本土[教育ネットワーク]3。海外地域" + echo "1. 中国本土 [デフォルト] 2. 中国本土 [教育ネットワーク] 3. 海外地域 4. 更新ソースのインテリジェントな切り替え" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "あなたの選択を入力してください:" choice + read -e -p "選択内容を入力してください:" choice case $choice in 1) - send_stats "中国本土のデフォルトソース" + send_stats "中国本土のデフォルトのソース" bash <(curl -sSL https://linuxmirrors.cn/main.sh) ;; 2) @@ -11436,9 +14026,14 @@ EOF bash <(curl -sSL https://linuxmirrors.cn/main.sh) --edu ;; 3) - send_stats "海外起源" + send_stats "海外情報源" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "アップデートソースのインテリジェントな切り替え" + switch_mirror false false + ;; + *) echo "キャンセル" ;; @@ -11448,62 +14043,62 @@ EOF ;; 20) - send_stats "タイミングタスク管理" + send_stats "スケジュールされたタスクの管理" while true; do clear check_crontab_installed clear - echo "タイミングされたタスクリスト" + echo "スケジュールされたタスクのリスト" crontab -l echo "" - echo "動作します" + echo "操作する" echo "------------------------" - echo "1.タイミングタスクの追加2。タイミングタスクを削除する3。タイミングタスクの編集" + echo "1. スケジュールされたタスクを追加します。 2. スケジュールされたタスクを削除します。 3. スケジュールされたタスクを編集します。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) - read -e -p "新しいタスクについては、実行コマンドを入力してください。" newquest + read -e -p "新しいタスクの実行コマンドを入力してください:" newquest echo "------------------------" - echo "1。毎月のタスク2。毎週のタスク" - echo "3。毎日のタスク4。時間ごとのタスク" + echo "1. 月次タスク 2. 週次タスク" + echo "3. 毎日のタスク 4. 時間ごとのタスク" echo "------------------------" - read -e -p "選択を入力してください:" dingshi + read -e -p "選択肢を入力してください:" dingshi case $dingshi in 1) - read -e -p "毎月何日を選択してタスクを実行しますか? (1-30):" day + read -e -p "タスクを実行する日は月の何日ですか? (1-30):" day (crontab -l ; echo "0 0 $day * * $newquest") | crontab - > /dev/null 2>&1 ;; 2) - read -e -p "タスクを実行するためにどの週を選択しますか? (0-6、0は日曜日を表します):" weekday + read -e -p "タスクを実行する曜日を選択しますか? (0 ~ 6、0 は日曜日を表します):" weekday (crontab -l ; echo "0 0 * * $weekday $newquest") | crontab - > /dev/null 2>&1 ;; 3) - read -e -p "毎日タスクを実行する時間を選択しますか? (時間、0-23):" hour + read -e -p "毎日、そのタスクを実行する時刻を選択しますか? (時、0-23):" hour (crontab -l ; echo "0 $hour * * * $newquest") | crontab - > /dev/null 2>&1 ;; 4) - read -e -p "タスクを実行するために時間の何時間を入力しますか? (分、0-60):" minute + read -e -p "タスクを実行する時間を入力してください。 (分、0 ~ 60):" minute (crontab -l ; echo "$minute * * * * $newquest") | crontab - > /dev/null 2>&1 ;; *) break # 跳出 ;; esac - send_stats "時限タスクを追加します" + send_stats "スケジュールされたタスクを追加する" ;; 2) - read -e -p "削除する必要があるキーワードを入力してください。" kquest + read -e -p "削除するタスクのキーワードを入力してください:" kquest crontab -l | grep -v "$kquest" | crontab - - send_stats "タイミングタスクを削除します" + send_stats "スケジュールされたタスクを削除する" ;; 3) crontab -e - send_stats "タイミングタスクを編集します" + send_stats "スケジュールされたタスクを編集する" ;; *) break # 跳出循环,退出菜单 @@ -11515,32 +14110,32 @@ EOF 21) root_use - send_stats "ローカルホストの解析" + send_stats "ローカルホストの解決" while true; do clear - echo "ネイティブホストのペルシングリスト" - echo "ここに解析の一致を追加すると、動的な解析はもはや使用されなくなります" + echo "ネイティブホスト解決リスト" + echo "ここに解析一致を追加すると、動的解析は使用されなくなります" cat /etc/hosts echo "" - echo "動作します" + echo "操作する" echo "------------------------" - echo "1.新しい解析2を追加します。解析アドレスを削除します" + echo "1. 新しい解決策を追加 2. 解決策アドレスを削除" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" host_dns + read -e -p "選択肢を入力してください:" host_dns case $host_dns in 1) - read -e -p "新しい解析レコード形式を入力してください:110.25.5.33 Kejilion.pro:" addhost + read -e -p "新しい解析レコード形式を入力してください: 110.25.5.33 kejilion.pro:" addhost echo "$addhost" >> /etc/hosts - send_stats "ローカルホストの解析が追加されました" + send_stats "ローカルホストの解像度が追加されました" ;; 2) - read -e -p "削除する必要があるコンテンツの解析のキーワードを入力してください。" delhost + read -e -p "削除する必要がある解析済みコンテンツのキーワードを入力してください:" delhost sed -i "/$delhost/d" /etc/hosts - send_stats "ローカルホストの解析と削除" + send_stats "ローカルホストの解決と削除" ;; *) break # 跳出循环,退出菜单 @@ -11550,63 +14145,7 @@ EOF ;; 22) - root_use - send_stats "SSH防御" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH防衛プログラム$check_docker" - echo "Fail2banは、ブルートフォースを防ぐためのSSHツールです" - echo "公式ウェブサイトの紹介:${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1.防衛プログラムをインストールします" - echo "------------------------" - echo "2。SSH傍受記録を表示します" - echo "3。リアルタイムログ監視" - echo "------------------------" - echo "9.防衛プログラムをアンインストールします" - echo "------------------------" - echo "0。前のメニューに戻ります" - echo "------------------------" - read -e -p "選択を入力してください:" sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2Ban防衛プログラムがアンインストールされています" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; @@ -11616,43 +14155,43 @@ EOF while true; do clear echo "電流制限シャットダウン機能" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1mc411j7qd?t=0.1" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1mC411j7Qd?t=0.1" echo "------------------------------------------------" - echo "現在のトラフィックの使用、サーバートラフィックの計算の再起動がクリアされます!" + echo "現在のトラフィック使用量は、サーバーが再起動されるとクリアされます。" output_status - echo -e "${gl_kjlan}合計受信:${gl_bai}$rx" - echo -e "${gl_kjlan}合計送信:${gl_bai}$tx" + echo -e "${gl_kjlan}受け取った合計:${gl_bai}$rx" + echo -e "${gl_kjlan}送信合計:${gl_bai}$tx" - # limiting_shut_down.shファイルが存在するかどうかを確認してください + # Limiting_Shut_down.sh ファイルが存在するかどうかを確認します if [ -f ~/Limiting_Shut_down.sh ]; then - # threshold_gbの値を取得します + # しきい値_gbの値を取得する local rx_threshold_gb=$(grep -oP 'rx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) local tx_threshold_gb=$(grep -oP 'tx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) - echo -e "${gl_lv}現在のセットエントリステーション電流制限しきい値は次のとおりです。${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" - echo -e "${gl_lv}現在のアウトバウンド電流制限しきい値は次のとおりです。${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" + echo -e "${gl_lv}現在設定されている受信トラフィック制限のしきい値は次のとおりです。${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" + echo -e "${gl_lv}現在設定されている送信トラフィック制限のしきい値は次のとおりです。${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" else - echo -e "${gl_hui}現在の制限シャットダウン機能は有効になりません${gl_bai}" + echo -e "${gl_hui}電流制限シャットダウン機能は現在有効になっていません。${gl_bai}" fi echo echo "------------------------------------------------" - echo "システムは、実際のトラフィックが毎分でしきい値に達するかどうかを検出し、サーバーが到着した後にサーバーが自動的にシャットダウンされます!" + echo "システムは実際のトラフィックがしきい値に達したかどうかを毎分検出し、しきい値に達するとサーバーを自動的にシャットダウンします。" echo "------------------------" - echo "1。現在の制限シャットダウン関数をオンにします2。現在の制限シャットダウン機能を無効にします" + echo "1. 電流制限シャットダウン機能を有効にする 2. 電流制限シャットダウン機能を無効にする" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" Limiting + read -e -p "選択肢を入力してください:" Limiting case "$Limiting" in 1) - # 新しい仮想メモリサイズを入力します - echo "実際のサーバーに100gのトラフィックがある場合、しきい値を95gに設定し、事前に電源をシャットダウンして、トラフィックエラーやオーバーフローを回避できます。" - read -e -p "着信トラフィックのしきい値を入力してください(ユニットはG、デフォルトは100gです):" rx_threshold_gb + # 新しい仮想メモリ サイズを入力してください + echo "実際のサーバーのトラフィックが 100G しかない場合は、しきい値を 95G に設定し、事前にシャットダウンして、トラフィック エラーやオーバーフローを回避できます。" + read -e -p "受信トラフィックのしきい値を入力してください (単位は G、デフォルトは 100G):" rx_threshold_gb rx_threshold_gb=${rx_threshold_gb:-100} - read -e -p "アウトバウンドトラフィックのしきい値を入力してください(ユニットはG、デフォルトは100gです):" tx_threshold_gb + read -e -p "送信トラフィックのしきい値を入力してください (単位は G、デフォルトは 100G):" tx_threshold_gb tx_threshold_gb=${tx_threshold_gb:-100} - read -e -p "トラフィックリセット日を入力してください(デフォルトのリセットは、毎月1日目にリセットされます):" cz_day + read -e -p "トラフィックのリセット日を入力してください (デフォルトは毎月 1 日にリセットされます)。" cz_day cz_day=${cz_day:-1} cd ~ @@ -11665,15 +14204,15 @@ EOF (crontab -l ; echo "* * * * * ~/Limiting_Shut_down.sh") | crontab - > /dev/null 2>&1 crontab -l | grep -v 'reboot' | crontab - (crontab -l ; echo "0 1 $cz_day * * reboot") | crontab - > /dev/null 2>&1 - echo "現在の制限シャットダウンが設定されています" - send_stats "現在の制限シャットダウンが設定されています" + echo "電流制限シャットダウンが設定されています" + send_stats "電流制限シャットダウンが設定されています" ;; 2) check_crontab_installed crontab -l | grep -v '~/Limiting_Shut_down.sh' | crontab - crontab -l | grep -v 'reboot' | crontab - rm ~/Limiting_Shut_down.sh - echo "現在の制限シャットダウン関数はオフになっています" + echo "電流制限シャットダウン機能がオフになる" ;; *) break @@ -11686,40 +14225,40 @@ EOF 24) root_use - send_stats "秘密キーログイン" + send_stats "秘密キーによるログイン" while true; do clear - echo "ルート秘密キーログインモード" - echo "ビデオの紹介:https://www.bilibili.com/video/bv1q4421x78n?t=209.4" + echo "ROOT秘密鍵ログインモード" + echo "ビデオ紹介: https://www.bilibili.com/video/BV1Q4421X78n?t=209.4" echo "------------------------------------------------" - echo "キーペアが生成され、SSHログインのより安全な方法" + echo "キーペアが生成され、SSH 経由でログインするためのより安全な方法になります。" echo "------------------------" - echo "1.新しいキーを生成する2。既存のキーをインポートする3。ネイティブキーを表示します" + echo "1. 新しいキーを生成します。 2. 既存のキーをインポートします。 3. ローカルキーを表示します。" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" host_dns + read -e -p "選択肢を入力してください:" host_dns case $host_dns in 1) - send_stats "新しいキーを生成します" + send_stats "新しいキーを生成する" add_sshkey break_end ;; 2) - send_stats "既存の公開キーをインポートします" + send_stats "既存の公開キーをインポートする" import_sshkey break_end ;; 3) - send_stats "地元の秘密の鍵を表示します" + send_stats "ローカルキーを表示する" echo "------------------------" echo "公開鍵情報" cat ~/.ssh/authorized_keys echo "------------------------" - echo "秘密のキー情報" + echo "秘密鍵情報" cat ~/.ssh/sshkey echo "------------------------" break_end @@ -11735,18 +14274,18 @@ EOF 25) root_use - send_stats "電報警告" - echo "TG-BOTモニタリングと早期警告機能" - echo "ビデオの紹介:https://youtu.be/vll-eb3z_ty" + send_stats "電報警報" + echo "TG-bot監視・早期警告機能" + echo "動画紹介:https://youtu.be/vLL-eb3Z_TY" echo "------------------------------------------------" - echo "ネイティブCPU、メモリ、ハードディスク、トラフィック、およびSSHログインのリアルタイム監視と早期警告を実現するために、TG Robot APIとユーザーIDを構成する必要があります。" - echo "しきい値に達した後、ユーザーはユーザーに送信されます" - echo -e "${gl_hui}- トラフィックに関しては、サーバーの再起動が再計算されます -${gl_bai}" - read -e -p "必ず続行しますか? (y/n):" choice + echo "ローカル CPU、メモリ、ハードディスク、トラフィック、SSH ログインのリアルタイム監視とアラートを実現するには、tg robot API とアラートを受信するユーザー ID を設定する必要があります。" + echo "しきい値に達すると、警告メッセージがユーザーに送信されます。" + echo -e "${gl_hui}- 通信量についてはサーバーを再起動すると再計算されます -${gl_bai}" + read -e -p "続行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) - send_stats "電報警告が有効になっています" + send_stats "テレグラム警告が有効になっています" cd ~ install nano tmux bc jq check_crontab_installed @@ -11768,7 +14307,7 @@ EOF sed -i "4i$(grep '^CHAT_ID=' ~/TG-check-notify.sh)" TG-SSH-check-notify.sh chmod +x ~/TG-SSH-check-notify.sh - # 〜/.Profileファイルに追加します + # ~/.profile ファイルに追加 if ! grep -q 'bash ~/TG-SSH-check-notify.sh' ~/.profile > /dev/null 2>&1; then echo 'bash ~/TG-SSH-check-notify.sh' >> ~/.profile if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -11779,21 +14318,21 @@ EOF source ~/.profile clear - echo "TG-BOT早期警告システムが開始されました" - echo -e "${gl_hui}他のマシンのルートディレクトリにTG-Check-notify.sh警告ファイルを配置して、直接使用することもできます。${gl_bai}" + echo "TG-bot早期警戒システムが作動しました" + echo -e "${gl_hui}TG-check-notify.sh 警告ファイルを他のマシンのルート ディレクトリに置き、それを直接使用することもできます。${gl_bai}" ;; [Nn]) echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; 26) root_use - send_stats "SSHの高リスクの脆弱性を修正します" + send_stats "高リスクの SSH 脆弱性を修正する" cd ~ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/upgrade_openssh9.8p1.sh chmod +x ~/upgrade_openssh9.8p1.sh @@ -11853,98 +14392,102 @@ EOF ;; + 39) + clear + linux_fav + ;; + 41) clear - send_stats "メッセージボード" - echo "テクノロジーライオンメッセージボードは公式コミュニティに移動されました!公式コミュニティにメッセージを残してください!" - echo "https://bbs.kejilion.pro/" + send_stats "掲示板" + echo "Technology Lion の公式掲示板をご覧ください。脚本についてのアイデアがあれば、メッセージを残して交換してください。" + echo "https://board.kejilion.pro" + echo "公開パスワード: kejilion.sh" ;; 66) root_use send_stats "ワンストップチューニング" - echo "ワンストップシステムの最適化" + echo "ワンストップのシステムチューニング" echo "------------------------------------------------" - echo "以下が操作され、最適化されます" - echo "1.システムを最新の状態に更新します" - echo "2。システムジャンクファイルをクリーンアップします" - echo -e "3.仮想メモリを設定します${gl_huang}1G${gl_bai}" - echo -e "4. SSHポート番号をに設定します${gl_huang}5522${gl_bai}" - echo -e "5.すべてのポートを開きます" - echo -e "6。電源を入れます${gl_huang}BBR${gl_bai}加速します" - echo -e "7.タイムゾーンをに設定します${gl_huang}上海${gl_bai}" - echo -e "8。DNSアドレスを自動的に最適化します${gl_huang}海外:1.1.1.1 8.8.8.8国内:223.5.5.5${gl_bai}" - echo -e "9.基本ツールをインストールします${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10。Linuxシステムのカーネルパラメーター最適化に切り替えます${gl_huang}バランスの取れた最適化モード${gl_bai}" + echo "以下のコンテンツを運用・最適化していきます" + echo "1. システムアップデートソースを最適化し、システムを最新の状態にアップデートします。" + echo "2. システムジャンクファイルをクリーンアップする" + echo -e "3. 仮想メモリを設定する${gl_huang}1G${gl_bai}" + echo -e "4. SSH ポート番号を次のように設定します。${gl_huang}5522${gl_bai}" + echo -e "5. SSH ブルート フォース クラッキングを防ぐために、fail2ban を開始します。" + echo -e "6.すべてのポートを開きます" + echo -e "7.電源を入れます${gl_huang}BBR${gl_bai}加速する" + echo -e "8. タイムゾーンを次のように設定します。${gl_huang}上海${gl_bai}" + echo -e "9. DNS アドレスを自動的に最適化する${gl_huang}海外:1.1.1.1 8.8.8.8 国内:223.5.5.5${gl_bai}" + echo -e "10. ネットワークを次のように設定します。${gl_huang}IPv4優先度${gl_bai}" + echo -e "11. 基本ツールのインストール${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux システムのカーネル パラメータの最適化は、${gl_huang}バランスのとれた最適化モード${gl_bai}" echo "------------------------------------------------" - read -e -p "ワンクリックメンテナンスは必ずありますか? (y/n):" choice + read -e -p "ワンクリックメンテナンスを実行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) clear - send_stats "ワンストップチューニングスタート" + send_stats "ワンストップチューニングが始まります" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10。システムを最新の状態に更新します" + echo -e "[${gl_lv}OK${gl_bai}】1/12。システムを最新のものにアップデートする" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10。システムジャンクファイルをクリーンアップします" + echo -e "[${gl_lv}OK${gl_bai}】2/12。システムのジャンクファイルをクリーンアップする" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10。仮想メモリを設定します${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}】3/12。仮想メモリを設定する${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10。 SSHポート番号をに設定します${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}】4/12。 SSH ポート番号を次のように設定します。${gl_huang}5522${gl_bai}" + echo "------------------------------------------------" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}】5/12。 SSH ブルート フォース クラッキングを防ぐために、fail2ban を開始します。" + echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10。すべてのポートを開きます" + echo -e "[${gl_lv}OK${gl_bai}】6/12。すべてのポートを開く" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10。開ける${gl_huang}BBR${gl_bai}加速します" + echo -e "[${gl_lv}OK${gl_bai}】7/12。開ける${gl_huang}BBR${gl_bai}加速する" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10。タイムゾーンをに設定します${gl_huang}上海${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}】8/12。タイムゾーンを次のように設定します${gl_huang}上海${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10。 DNSアドレスを自動的に最適化します${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}】9/12。 DNSアドレスを自動的に最適化する${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}】10/12。ネットワークを次のように設定します${gl_huang}IPv4優先度${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10。基本ツールをインストールします${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}】11/12。基本的なツールをインストールする${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10。 Linuxシステムのカーネルパラメーターの最適化" - echo -e "${gl_lv}ワンストップシステムのチューニングが完了しました${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}】12/12。 Linuxシステムのカーネルパラメータの最適化" + echo -e "${gl_lv}ワンストップでのシステムチューニングが完了${gl_bai}" ;; [Nn]) echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac @@ -11961,39 +14504,39 @@ EOF while true; do clear if grep -q '^ENABLE_STATS="true"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_lv}正在采集数据${gl_bai}" + local status_message="${gl_lv}データの収集${gl_bai}" elif grep -q '^ENABLE_STATS="false"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_hui}采集已关闭${gl_bai}" + local status_message="${gl_hui}コレクションは終了しました${gl_bai}" else - local status_message="无法确定的状态" + local status_message="不確実なステータス" fi echo "プライバシーとセキュリティ" - echo "スクリプトは、ユーザー機能に関するデータを収集し、スクリプトエクスペリエンスを最適化し、より楽しく便利な機能を作成します。" - echo "スクリプトバージョン番号、使用時間、システムバージョン、CPUアーキテクチャ、マシンの国、および使用される関数の名前を収集します。" + echo "スクリプトはユーザーによる機能の使用に関するデータを収集し、スクリプト エクスペリエンスを最適化し、より楽しくて便利な機能を作成します。" + echo "スクリプトのバージョン番号、使用時間、システムバージョン、CPUアーキテクチャ、マシンの国、使用された機能の名前が収集されます。" echo "------------------------------------------------" - echo -e "現在のステータス:$status_message" + echo -e "現在のステータス:$status_message" echo "--------------------" - echo "1。コレクションをオンにします" - echo "2。コレクションを閉じます" + echo "1.収集を開始する" + echo "2. コレクションを閉じる" echo "--------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "--------------------" - read -e -p "選択を入力してください:" sub_choice + read -e -p "選択肢を入力してください:" sub_choice case $sub_choice in 1) cd ~ sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' ~/kejilion.sh - echo "コレクションが有効になっています" - send_stats "プライバシーとセキュリティコレクションが有効になっています" + echo "収集が開始されました" + send_stats "プライバシーとセキュリティの収集がオンになっています" ;; 2) cd ~ sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' ~/kejilion.sh - echo "コレクションは閉じた" - send_stats "プライバシーとセキュリティは収集のために閉鎖されています" + echo "コレクションは終了しました" + send_stats "プライバシーとセキュリティの収集がオフになっています" ;; *) break @@ -12009,11 +14552,11 @@ EOF 102) clear - send_stats "テックライオンスクリプトをアンインストールします" - echo "テックライオンスクリプトをアンインストールします" + send_stats "Tech Lion スクリプトをアンインストールする" + echo "Tech Lion スクリプトをアンインストールする" echo "------------------------------------------------" - echo "Kejilionスクリプトを完全にアンインストールし、他の機能には影響しません" - read -e -p "必ず続行しますか? (y/n):" choice + echo "kejilion スクリプトは、他の機能に影響を与えることなく完全にアンインストールされます。" + read -e -p "続行してもよろしいですか? (はい/いいえ):" choice case "$choice" in [Yy]) @@ -12021,7 +14564,7 @@ EOF (crontab -l | grep -v "kejilion.sh") | crontab - rm -f /usr/local/bin/k rm ~/kejilion.sh - echo "スクリプトはアンインストールされています、さようなら!" + echo "スクリプトはアンインストールされました、さようなら!" break_end clear exit @@ -12030,7 +14573,7 @@ EOF echo "キャンセル" ;; *) - echo "無効な選択、yまたはnを入力してください。" + echo "選択が無効です。Y または N を入力してください。" ;; esac ;; @@ -12040,7 +14583,7 @@ EOF ;; *) - echo "無効な入力!" + echo "無効な入力です!" ;; esac break_end @@ -12068,174 +14611,174 @@ linux_file() { echo "------------------------" ls --color=auto -x echo "------------------------" - echo "1.ディレクトリ2を入力します。ディレクトリを作成3。ディレクトリアクセス許可を変更します。4。ディレクトリの名前を変更します" - echo "5.ディレクトリを削除6。前のメニューディレクトリに戻ります" + echo "1. ディレクトリを入力します。 2. ディレクトリを作成します。 3. ディレクトリのアクセス許可を変更します。 4. ディレクトリの名前を変更します。" + echo "5. ディレクトリを削除します。 6. 前のメニュー ディレクトリに戻ります。" echo "------------------------" - echo "11。ファイルを作成する12。ファイル13を編集します。ファイル許可を変更14。ファイルの名前を変更します" - echo "15.ファイルを削除します" + echo "11. ファイルの作成 12. ファイルの編集 13. ファイル権限の変更 14. ファイル名の変更" + echo "15. ファイルの削除" echo "------------------------" - echo "21。ファイルディレクトリの圧縮22。UNZIPファイルディレクトリ23。ファイルディレクトリの移動24。ファイルディレクトリをコピーする" - echo "25。ファイルを別のサーバーに渡します" + echo "21. ファイル ディレクトリの圧縮 22. ファイル ディレクトリの解凍 23. ファイル ディレクトリの移動 24. ファイル ディレクトリのコピー" + echo "25. 他のサーバーにファイルを転送する" echo "------------------------" - echo "0。前のメニューに戻ります" + echo "0. 前のメニューに戻る" echo "------------------------" - read -e -p "選択を入力してください:" Limiting + read -e -p "選択肢を入力してください:" Limiting case "$Limiting" in 1) # 进入目录 - read -e -p "ディレクトリ名を入力してください:" dirname - cd "$dirname" 2>/dev/null || echo "ディレクトリを入力できません" - send_stats "ディレクトリに移動します" + read -e -p "ディレクトリ名を入力してください:" dirname + cd "$dirname" 2>/dev/null || echo "ディレクトリに入れません" + send_stats "ディレクトリを入力してください" ;; 2) # 创建目录 - read -e -p "作成するにはディレクトリ名を入力してください。" dirname - mkdir -p "$dirname" && echo "作成されたディレクトリ" || echo "作成に失敗しました" - send_stats "ディレクトリを作成します" + read -e -p "作成するディレクトリ名を入力してください:" dirname + mkdir -p "$dirname" && echo "ディレクトリが作成されました" || echo "作成に失敗しました" + send_stats "ディレクトリの作成" ;; 3) # 修改目录权限 - read -e -p "ディレクトリ名を入力してください:" dirname - read -e -p "許可を入力してください(755など):" perm - chmod "$perm" "$dirname" && echo "許可が変更されました" || echo "変更に失敗しました" - send_stats "ディレクトリ権限を変更します" + read -e -p "ディレクトリ名を入力してください:" dirname + read -e -p "権限を入力してください (例: 755):" perm + chmod "$perm" "$dirname" && echo "権限が変更されました" || echo "変更に失敗しました" + send_stats "ディレクトリの権限を変更する" ;; 4) # 重命名目录 - read -e -p "現在のディレクトリ名を入力してください:" current_name - read -e -p "新しいディレクトリ名を入力してください:" new_name - mv "$current_name" "$new_name" && echo "ディレクトリの名前が変更されました" || echo "名前変更に失敗しました" - send_stats "ディレクトリの名前を変更します" + read -e -p "現在のディレクトリ名を入力してください:" current_name + read -e -p "新しいディレクトリ名を入力してください:" new_name + mv "$current_name" "$new_name" && echo "ディレクトリの名前が変更されました" || echo "名前の変更に失敗しました" + send_stats "ディレクトリの名前を変更する" ;; 5) # 删除目录 - read -e -p "削除するには、ディレクトリ名を入力してください。" dirname - rm -rf "$dirname" && echo "ディレクトリが削除されました" || echo "削除が失敗しました" - send_stats "ディレクトリを削除します" + read -e -p "削除するディレクトリ名を入力してください:" dirname + rm -rf "$dirname" && echo "ディレクトリが削除されました" || echo "削除に失敗しました" + send_stats "ディレクトリを削除する" ;; 6) # 返回上一级选单目录 cd .. - send_stats "前のメニューディレクトリに戻ります" + send_stats "前のメニュー ディレクトリに戻る" ;; 11) # 创建文件 - read -e -p "作成するにはファイル名を入力してください。" filename - touch "$filename" && echo "作成されたファイル" || echo "作成に失敗しました" - send_stats "ファイルを作成します" + read -e -p "作成するファイル名を入力してください:" filename + touch "$filename" && echo "ファイルが作成されました" || echo "作成に失敗しました" + send_stats "ファイルの作成" ;; 12) # 编辑文件 - read -e -p "編集するにはファイル名を入力してください:" filename + read -e -p "編集するファイル名を入力してください:" filename install nano nano "$filename" - send_stats "ファイルを編集します" + send_stats "ファイルを編集する" ;; 13) # 修改文件权限 - read -e -p "ファイル名を入力してください:" filename - read -e -p "許可を入力してください(755など):" perm - chmod "$perm" "$filename" && echo "許可が変更されました" || echo "変更に失敗しました" - send_stats "ファイル権限を変更します" + read -e -p "ファイル名を入力してください:" filename + read -e -p "権限を入力してください (例: 755):" perm + chmod "$perm" "$filename" && echo "権限が変更されました" || echo "変更に失敗しました" + send_stats "ファイル権限を変更する" ;; 14) # 重命名文件 - read -e -p "現在のファイル名を入力してください:" current_name - read -e -p "新しいファイル名を入力してください:" new_name - mv "$current_name" "$new_name" && echo "名前の変更" || echo "名前変更に失敗しました" - send_stats "ファイルの名前を変更します" + read -e -p "現在のファイル名を入力してください:" current_name + read -e -p "新しいファイル名を入力してください:" new_name + mv "$current_name" "$new_name" && echo "ファイル名が変更されました" || echo "名前の変更に失敗しました" + send_stats "ファイル名の変更" ;; 15) # 删除文件 - read -e -p "削除するには、ファイル名を入力してください。" filename - rm -f "$filename" && echo "削除されたファイル" || echo "削除が失敗しました" - send_stats "ファイルを削除します" + read -e -p "削除するファイル名を入力してください:" filename + rm -f "$filename" && echo "ファイルが削除されました" || echo "削除に失敗しました" + send_stats "ファイルの削除" ;; 21) # 压缩文件/目录 - read -e -p "圧縮するには、ファイル/ディレクトリ名を入力してください。" name + read -e -p "圧縮するファイル/ディレクトリ名を入力してください:" name install tar - tar -czvf "$name.tar.gz" "$name" && echo "圧縮$name.tar.gz" || echo "圧縮に失敗しました" + tar -czvf "$name.tar.gz" "$name" && echo "に圧縮$name.tar.gz" || echo "圧縮に失敗しました" send_stats "圧縮ファイル/ディレクトリ" ;; 22) # 解压文件/目录 - read -e -p "ファイル名(.tar.gz)を入力してください:" filename + read -e -p "抽出するファイル名 (.tar.gz) を入力してください:" filename install tar - tar -xzvf "$filename" && echo "減圧$filename" || echo "減圧が失敗しました" - send_stats "ファイル/ディレクトリを解凍します" + tar -xzvf "$filename" && echo "解凍された$filename" || echo "解凍に失敗しました" + send_stats "ファイル/ディレクトリを解凍する" ;; 23) # 移动文件或目录 - read -e -p "移動するには、ファイルまたはディレクトリパスを入力してください。" src_path + read -e -p "移動するファイルまたはディレクトリのパスを入力してください:" src_path if [ ! -e "$src_path" ]; then - echo "エラー:ファイルまたはディレクトリは存在しません。" - send_stats "ファイルまたはディレクトリの移動に失敗しました:ファイルまたはディレクトリは存在しません" + echo "エラー: ファイルまたはディレクトリが存在しません。" + send_stats "ファイルまたはディレクトリの移動に失敗しました: ファイルまたはディレクトリが存在しません" continue fi - read -e -p "ターゲットパス(新しいファイル名またはディレクトリ名を含む)を入力してください。" dest_path + read -e -p "宛先パス (新しいファイル名またはディレクトリ名を含む) を入力してください:" dest_path if [ -z "$dest_path" ]; then - echo "エラー:ターゲットパスを入力してください。" - send_stats "ファイルまたはディレクトリの移動に失敗しました:宛先パスが指定されていません" + echo "エラー: 宛先パスを入力してください。" + send_stats "ファイルまたはディレクトリの移動に失敗しました: 宛先パスが指定されていません" continue fi - mv "$src_path" "$dest_path" && echo "ファイルまたはディレクトリが移動されました$dest_path" || echo "ファイルやディレクトリの移動に失敗しました" - send_stats "ファイルまたはディレクトリを移動します" + mv "$src_path" "$dest_path" && echo "ファイルまたはディレクトリの移動先$dest_path" || echo "ファイルまたはディレクトリの移動に失敗しました" + send_stats "ファイルまたはディレクトリを移動する" ;; 24) # 复制文件目录 - read -e -p "コピーするには、ファイルまたはディレクトリパスを入力してください。" src_path + read -e -p "コピーするファイルまたはディレクトリのパスを入力してください:" src_path if [ ! -e "$src_path" ]; then - echo "エラー:ファイルまたはディレクトリは存在しません。" - send_stats "ファイルまたはディレクトリのコピーに失敗しました:ファイルまたはディレクトリが存在しません" + echo "エラー: ファイルまたはディレクトリが存在しません。" + send_stats "ファイルまたはディレクトリのコピーに失敗しました: ファイルまたはディレクトリが存在しません" continue fi - read -e -p "ターゲットパス(新しいファイル名またはディレクトリ名を含む)を入力してください。" dest_path + read -e -p "宛先パス (新しいファイル名またはディレクトリ名を含む) を入力してください:" dest_path if [ -z "$dest_path" ]; then - echo "エラー:ターゲットパスを入力してください。" - send_stats "ファイルまたはディレクトリのコピーに失敗しました:宛先パスが指定されていない" + echo "エラー: 宛先パスを入力してください。" + send_stats "ファイルまたはディレクトリのコピーに失敗しました: 宛先パスが指定されていません" continue fi - # -Rオプションを使用して、ディレクトリを再帰的にコピーします - cp -r "$src_path" "$dest_path" && echo "ファイルまたはディレクトリがコピーされています$dest_path" || echo "ファイルまたはディレクトリのコピーに失敗しました" - send_stats "ファイルまたはディレクトリをコピーします" + # -r オプションを使用してディレクトリを再帰的にコピーします + cp -r "$src_path" "$dest_path" && echo "コピー先のファイルまたはディレクトリ$dest_path" || echo "ファイルまたはディレクトリのコピーに失敗しました" + send_stats "ファイルまたはディレクトリをコピーする" ;; 25) # 传送文件至远端服务器 - read -e -p "転送されるファイルパスを入力してください。" file_to_transfer + read -e -p "転送するファイル パスを入力してください:" file_to_transfer if [ ! -f "$file_to_transfer" ]; then - echo "エラー:ファイルは存在しません。" - send_stats "ファイルの転送に失敗しました:ファイルは存在しません" + echo "エラー: ファイルが存在しません。" + send_stats "ファイルの転送に失敗しました: ファイルが存在しません" continue fi - read -e -p "リモートサーバーIPを入力してください:" remote_ip + read -e -p "リモートサーバーのIPを入力してください:" remote_ip if [ -z "$remote_ip" ]; then - echo "エラー:リモートサーバーIPを入力してください。" - send_stats "ファイル転送に失敗しました:リモートサーバーIPは入力されませんでした" + echo "エラー: リモート サーバーの IP を入力してください。" + send_stats "ファイル転送に失敗しました: リモート サーバー IP が入力されていません" continue fi - read -e -p "リモートサーバーのユーザー名(デフォルトルート)を入力してください。" remote_user + read -e -p "リモート サーバーのユーザー名 (デフォルトの root) を入力してください:" remote_user remote_user=${remote_user:-root} - read -e -p "リモートサーバーのパスワードを入力してください:" -s remote_password + read -e -p "リモートサーバーのパスワードを入力してください:" -s remote_password echo if [ -z "$remote_password" ]; then - echo "エラー:リモートサーバーのパスワードを入力してください。" - send_stats "ファイル転送の失敗:リモートサーバーパスワードが入力されていません" + echo "エラー: リモート サーバーのパスワードを入力してください。" + send_stats "ファイル転送に失敗しました: リモートサーバーのパスワードが入力されていません" continue fi - read -e -p "ログインポートを入力してください(デフォルト22):" remote_port + read -e -p "ログイン ポートを入力してください (デフォルトは 22):" remote_port remote_port=${remote_port:-22} - # 既知のホストの古いエントリをクリアします + # 既知のホストの古いエントリをクリアする ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 等待时间 - # SCPを使用してファイルを転送します + # scpを使用してファイルを転送する scp -P "$remote_port" -o StrictHostKeyChecking=no "$file_to_transfer" "$remote_user@$remote_ip:/home/" < /dev/null 2>&1 - echo -e "${gl_lv}スクリプトは最新バージョンに更新されました!${gl_huang}v$sh_v_new${gl_bai}" + echo -e "${gl_lv}スクリプトが最新バージョンに更新されました。${gl_huang}v$sh_v_new${gl_bai}" send_stats "スクリプトは最新です$sh_v_new" break_end ~/kejilion.sh @@ -12536,15 +15137,15 @@ while true; do (crontab -l | grep -v "kejilion.sh") | crontab - # (crontab -l 2>/dev/null; echo "0 2 * * * bash -c \"$SH_Update_task\"") | crontab - (crontab -l 2>/dev/null; echo "$(shuf -i 0-59 -n 1) 2 * * * bash -c \"$SH_Update_task\"") | crontab - - echo -e "${gl_lv}自動更新が有効になり、スクリプトは毎日午前2時に自動的に更新されます!${gl_bai}" - send_stats "自動スクリプトの更新をオンにします" + echo -e "${gl_lv}自動更新がオンになっており、スクリプトは毎日午前 2 時に自動的に更新されます。${gl_bai}" + send_stats "スクリプトの自動更新を有効にする" break_end ;; 3) clear (crontab -l | grep -v "kejilion.sh") | crontab - - echo -e "${gl_lv}自動更新は閉じられています${gl_bai}" - send_stats "スクリプト自動更新を閉じます" + echo -e "${gl_lv}自動更新はオフになっています${gl_bai}" + send_stats "スクリプトの自動更新をオフにする" break_end ;; *) @@ -12566,41 +15167,40 @@ echo -e "${gl_kjlan}" echo "╦╔═╔═╗ ╦╦╦ ╦╔═╗╔╗╔ ╔═╗╦ ╦" echo "╠╩╗║╣ ║║║ ║║ ║║║║ ╚═╗╠═╣" echo "╩ ╩╚═╝╚╝╩╩═╝╩╚═╝╝╚╝o╚═╝╩ ╩" -echo -e "テクノロジーライオンスクリプトツールボックスv$sh_v" -echo -e "コマンドライン入力${gl_huang}k${gl_kjlan}スクリプトをすばやく開始します${gl_bai}" +echo -e "テクノロジー ライオン スクリプト ツールボックス v$sh_v" +echo -e "コマンドライン入力${gl_huang}k${gl_kjlan}クイックスタートスクリプト${gl_bai}" echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}1. ${gl_bai}システム情報クエリ" -echo -e "${gl_kjlan}2. ${gl_bai}システムの更新" +echo -e "${gl_kjlan}1. ${gl_bai}システム情報の問い合わせ" +echo -e "${gl_kjlan}2. ${gl_bai}システムアップデート" echo -e "${gl_kjlan}3. ${gl_bai}システムのクリーンアップ" echo -e "${gl_kjlan}4. ${gl_bai}基本的なツール" echo -e "${gl_kjlan}5. ${gl_bai}BBR管理" echo -e "${gl_kjlan}6. ${gl_bai}Docker管理" echo -e "${gl_kjlan}7. ${gl_bai}ワープ管理" -echo -e "${gl_kjlan}8. ${gl_bai}テストスクリプトコレクション" -echo -e "${gl_kjlan}9. ${gl_bai}Oracle Cloud Scriptコレクション" -echo -e "${gl_huang}10. ${gl_bai}LDNMP Webサイトビルディング" +echo -e "${gl_kjlan}8. ${gl_bai}テストスクリプト集" +echo -e "${gl_kjlan}9. ${gl_bai}Oracle Cloudスクリプト・コレクション" +echo -e "${gl_huang}10. ${gl_bai}LDNMP Web サイトの構築" echo -e "${gl_kjlan}11. ${gl_bai}アプリケーション市場" echo -e "${gl_kjlan}12. ${gl_bai}バックエンドワークスペース" echo -e "${gl_kjlan}13. ${gl_bai}システムツール" -echo -e "${gl_kjlan}14. ${gl_bai}サーバークラスター制御" -echo -e "${gl_kjlan}15. ${gl_bai}広告列" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}Phantom Beast Palu Serverオープニングスクリプト" +echo -e "${gl_kjlan}14. ${gl_bai}サーバークラスタ制御" +echo -e "${gl_kjlan}15. ${gl_bai}広告コラム" +echo -e "${gl_kjlan}16. ${gl_bai}ゲームサーバー起動スクリプト集" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}スクリプトの更新" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}0. ${gl_bai}スクリプトを終了します" echo -e "${gl_kjlan}------------------------${gl_bai}" -read -e -p "選択を入力してください:" choice +read -e -p "選択肢を入力してください:" choice case $choice in - 1) linux_ps ;; - 2) clear ; send_stats "システムの更新" ; linux_update ;; + 1) linux_info ;; + 2) clear ; send_stats "システムアップデート" ; linux_update ;; 3) clear ; send_stats "システムのクリーンアップ" ; linux_clean ;; 4) linux_tools ;; 5) linux_bbr ;; 6) linux_docker ;; - 7) clear ; send_stats "ワープ管理" ; install wget + 7) clear ; send_stats "反り管理" ; install wget wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh ; bash menu.sh [option] [lisence/url/token] ;; 8) linux_test ;; @@ -12611,13 +15211,10 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "Phantom Beast Palu Serverオープニングスクリプト" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; - *) echo "無効な入力!" ;; + *) echo "無効な入力です!" ;; esac break_end done @@ -12625,67 +15222,72 @@ done k_info() { -send_stats "Kコマンド参照ユースケース" +send_stats "k コマンドのリファレンス例" echo "-------------------" -echo "ビデオの紹介:https://www.bilibili.com/video/bv1ib421e7it?t=0.1" -echo "以下は、Kコマンドリファレンスユースケースです。" +echo "ビデオ紹介: https://www.bilibili.com/video/BV1ib421E7it?t=0.1" +echo "以下は、k コマンドの参考使用例です。" echo "スクリプトkを開始します" -echo "ソフトウェアパッケージkをインストールしますnano wgetをインストールします| k nano wgetを追加| K nano wgetをインストールします" -echo "パッケージのアンインストールk nano wgetを削除| k del nano wget | K UNINSTALLNANOWGET | K UNINSTALLNANO WGET" -echo "システムKアップデートを更新| Kアップデート" -echo "クリーンシステムガベージkクリーン| kきれい" -echo "システムパネルk dd |を再インストールしますk再インストール" -echo "BBR3コントロールパネルK BBR3 | K BBRV3" -echo "カーネルチューニングパネルk nhyh | Kカーネル最適化" -echo "仮想メモリkスワップ2048を設定します" -echo "仮想タイムゾーンKタイムアジア/上海|を設定しますKタイムゾーンアジア/上海" -echo "システムリサイクルビンKトラッシュ| K HSZ | Kリサイクルビン" -echo "システムバックアップ関数Kバックアップ| k bf | Kバックアップ" -echo "SSHリモート接続ツールK SSH | Kリモート接続" -echo "rsyncリモート同期ツールk rsync | Kリモート同期" -echo "ハードディスク管理ツールKディスク| Kハードディスク管理" -echo "イントラネット浸透(サーバー側)K FRP" -echo "イントラネット浸透(クライアント)K FRPC" -echo "ソフトウェアStart K Start SSHD | k sshdを開始します" -echo "ソフトウェアSTOP K STOP SSHD | k stop sshd" -echo "ソフトウェア再起動k再起動sshd | k再起動sshd" -echo "ソフトウェアステータスビューKステータスSSHD | KステータスSSHD" -echo "ソフトウェアブートk dockerを有効にする| K AutoStart Docke | Kスタートアップドッカー" -echo "ドメイン名証明書アプリケーションK SSL" -echo "ドメイン名証明書の有効期限クエリK SSL PS" -echo "Docker Environment Installation K Dockerインストール| K Dockerのインストール" -echo "Docker Container Management K Docker PS | K Dockerコンテナ" -echo "Docker Image Management K Docker IMG | K Docker画像" -echo "LDNMPサイト管理k Web" -echo "LDNMPキャッシュクリーンアップK Webキャッシュ" -echo "WordPress k wp | k wordpress | k wp xxx.comをインストールします" -echo "リバースプロキシk fd | k rp | k抗ジェネレーション| k fd xxx.comをインストールする" -echo "ロードバランスkロードバランス| kロードバランシングをインストールします" -echo "ファイアウォールパネルk fhq | kファイアウォール" -echo "オープンポートK DKDK 8080 | Kオープンポート8080" -echo "ポートK GBDK 7800を閉じる| kポート7800を閉じます" -echo "IP K FXIP 127.0.0.0/8 | KリリースIP 127.0.0.0/8をリリースします" -echo "ブロックIP K ZZIP 177.5.25.36 | KブロックIP 177.5.25.36" - - +echo "パッケージをインストールします k install nano wget | k ナノ wget を追加 | nano wgetをインストールします" +echo "パッケージをアンインストールします。 k 削除 nano wget | kデルナノwget | nano wget をアンインストールする | nano wgetをアンインストールします" +echo "システム k アップデートを更新 | kアップデート" +echo "クリーン系ジャンククリーン |きれいだ" +echo "システムパネルを再度取り付けます。 k再インストール" +echo "BBR3 コントロール パネル K BBR3 | k bbrv3" +echo "カーネル チューニング パネルk カーネルの最適化" +echo "仮想メモリ k スワップを設定 2048" +echo "仮想タイムゾーンを設定します k 時間 アジア/上海 | k タイムゾーン アジア/上海" +echo "システムごみ箱のゴミ箱 | k hz | k ごみ箱" +echo "システムバックアップ機能 kバックアップ | k bf | k バックアップ" +echo "ssh リモート接続ツール k ssh | k リモート接続" +echo "rsync リモート同期ツール k rsync | k リモート同期" +echo "ハードディスク管理ツール k ディスク | k ハードディスクの管理" +echo "イントラネット普及率 (サーバー) k frps" +echo "イントラネット浸透率 (クライアント) k frpc" +echo "ソフトウェア起動 k start sshd | sshdを起動します" +echo "ソフトウェア停止 k 停止 sshd | k ストップ sshd" +echo "ソフトウェア再起動 k 再起動 sshd | k sshdを再起動します" +echo "ソフトウェアのステータスを確認します。 k ステータス sshd | kステータスsshd" +echo "k ドッカーを有効にする | k 自動開始ドッカー | k ソフトウェアの起動時に Docker を有効にする" +echo "ドメイン名証明書アプリケーション k ssl" +echo "ドメイン名証明書の有効期限のクエリ k ssl ps" +echo "docker 管理プレーン k docker" +echo "docker 環境のインストール k docker install |k docker インストール" +echo "docker コンテナ管理 k docker ps |k docker コンテナ" +echo "docker イメージ管理 k docker img |k docker image" +echo "LDNMP サイト管理 k Web" +echo "LDNMP キャッシュのクリーニング k Web キャッシュ" +echo "WordPress をインストールします。 kワードプレス | k wp xxx.com" +echo "リバース プロキシをインストールします k fd |k rp |k リバース プロキシ |k fd xxx.com" +echo "ロード バランシングのインストール k ロード バランシング |k ロード バランシング" +echo "L4 ロード バランシング k ストリーム |k L4 ロード バランシングをインストールする" +echo "ファイアウォール パネル k fhq |k ファイアウォール" +echo "ポートを開きます k dkdk 8080 |k ポートを開きます 8080" +echo "ポート k gbdk 7800 を閉じる |k ポート 7800 を閉じる" +echo "リリース IP k fxip 127.0.0.0/8 |k リリース IP 127.0.0.0/8" +echo "ブロック IP k zzip 177.5.25.36 |k ブロック IP 177.5.25.36" +echo "コマンド お気に入り k お気に入り | k コマンドのお気に入り" +echo "アプリケーションマーケット管理kアプリ" +echo "申請番号の迅速な管理 k app 26 | kアプリ1パネル | k アプリ npm" +echo "フェイル 2 バン管理 k フェイル 2 バン | k f2b" +echo "システム情報を表示 k info" } if [ "$#" -eq 0 ]; then - # パラメーターがない場合は、インタラクティブロジックを実行します + # 引数なしで対話型ロジックを実行します kejilion_sh else - # パラメーターがある場合は、対応する関数を実行します + # パラメータがある場合は、対応する関数を実行します case $1 in install|add|安装) shift - send_stats "ソフトウェアをインストールします" + send_stats "ソフトウェアのインストール" install "$@" ;; remove|del|uninstall|卸载) shift - send_stats "ソフトウェアをアンインストールします" + send_stats "ソフトウェアのアンインストール" remove "$@" ;; update|更新) @@ -12719,7 +15321,7 @@ else rsync_run) shift - send_stats "タイム付きRSYNC同期" + send_stats "スケジュールされたrsync同期" run_task "$@" ;; @@ -12738,7 +15340,7 @@ else find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ポートは、サービスへのアクセスをブロックされています" + echo "IP+ポートはサービスへのアクセスをブロックされています" else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -12749,15 +15351,20 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift - send_stats "仮想メモリをすばやく設定します" + send_stats "仮想メモリをすばやくセットアップする" add_swap "$@" ;; time|时区) shift - send_stats "タイムゾーンをすばやく設定します" + send_stats "タイムゾーンを素早く設定" set_timedate "$@" ;; @@ -12799,14 +15406,18 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift - send_stats "ソフトウェアステータスビュー" + send_stats "ソフトウェアのステータスを確認する" status "$@" ;; start|启动) shift - send_stats "ソフトウェアスタートアップ" + send_stats "ソフトウェアの起動" start "$@" ;; stop|停止) @@ -12822,14 +15433,14 @@ else enable|autostart|开机启动) shift - send_stats "ソフトウェアが起動します" + send_stats "起動時にソフトウェアが自動的に起動します" enable "$@" ;; ssl) shift if [ "$1" = "ps" ]; then - send_stats "証明書のステータスを確認してください" + send_stats "証明書ステータスの表示" ssl_ps elif [ -z "$1" ]; then add_ssl @@ -12846,19 +15457,19 @@ else shift case $1 in install|安装) - send_stats "Dockerをすばやくインストールします" + send_stats "Docker をすばやくインストールする" install_docker ;; ps|容器) - send_stats "クイックコンテナ管理" + send_stats "迅速なコンテナ管理" docker_ps ;; img|镜像) - send_stats "クイックミラー管理" + send_stats "素早い画像管理" docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -12878,6 +15489,22 @@ else fi ;; + + app) + shift + send_stats "申し込む$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/kejilion.sh b/kejilion.sh index 78bf8ceca..2b319bdc2 100644 --- a/kejilion.sh +++ b/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.5" +sh_v="4.3.2" gl_hui='\e[37m' @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -213,12 +213,15 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then echo -e "${gl_huang}提示: ${gl_bai}磁盘空间不足!" echo "当前可用空间: $((available_space_mb/1024))G" echo "最小需求空间: ${required_gb}G" @@ -230,8 +233,15 @@ check_disk_space() { } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,18 +417,31 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } @@ -426,61 +449,8 @@ install_add_docker_cn install_add_docker() { echo -e "${gl_huang}正在安装docker环境...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -1025,91 +995,84 @@ disable_ddos_defense() { # 管理国家IP规则的函数 manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # 如果 ipset 不存在则创建 - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # 下载 IP 区域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "错误:下载 $country_code 的 IP 区域文件失败" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 将 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "错误:下载 $country_code 的 IP 区域文件失败" + continue + fi - # 使用 iptables 阻止 IP - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "已成功阻止 $country_code 的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # 为允许的国家创建 ipset(如果不存在) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "已成功阻止 $country_code 的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 下载 IP 区域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "错误:下载 $country_code 的 IP 区域文件失败" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 删除现有的国家规则 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "错误:下载 $country_code 的 IP 区域文件失败" + continue + fi - # 将 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # 仅允许指定国家的 IP - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "已成功仅允许 $country_code 的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # 删除国家的 iptables 规则 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "已成功允许 $country_code 的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 销毁 ipset - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "已成功解除 $country_code 的 IP 地址限制" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "已成功解除 $country_code 的 IP 地址限制" + ;; + + *) + echo "用法: manage_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables @@ -1223,18 +1186,18 @@ iptables_panel() { ;; 15) - read -e -p "请输入阻止的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入阻止的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules block $country_code send_stats "允许国家 $country_code 的IP" ;; 16) - read -e -p "请输入允许的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入允许的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules allow $country_code send_stats "阻止国家 $country_code 的IP" ;; 17) - read -e -p "请输入清除的国家代码(如 CN, US, JP): " country_code + read -e -p "请输入清除的国家代码(多个国家代码可用空格隔开如 CN US JP): " country_code manage_country_rules unblock $country_code send_stats "清除国家 $country_code 的IP" ;; @@ -1252,8 +1215,6 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 @@ -1342,11 +1303,9 @@ ldnmp_v() { install_ldnmp_conf() { # 创建必要的目录和文件 - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx web/letsencrypt && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "letsencrypt" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # 获取国家代码(如 CN、US 等) + local country=$(curl -s ipinfo.io/country) + + # 根据国家设置 DNS + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "已切换为 IPv4 优先" +send_stats "已切换为 IPv4 优先" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,8 +1392,16 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # mysql调优 + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear echo "LDNMP环境安装完毕" @@ -1428,7 +1433,7 @@ install_ssltls() { local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1443,11 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1475,7 +1484,7 @@ if [ -z "$yuming" ]; then fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1534,12 +1543,77 @@ certs_status() { echo -e "4. 防火墙限制 ➠ 检查80/443端口是否开放,确保验证可访问" echo -e "5. 申请次数超限 ➠ Let's Encrypt有每周限额(5次/域名/周)" echo -e "6. 国内备案限制 ➠ 中国大陆环境请确认域名是否备案" - break_end - clear - echo "请再次尝试部署 $webname" - add_yuming - install_ssltls - certs_status + echo "------------------------" + echo "1. 重新申请 2. 导入已有证书 3. 不带证书改用HTTP访问 0. 退出" + echo "------------------------" + read -e -p "请输入你的选择: " sub_choice + case $sub_choice in + 1) + send_stats "重新申请" + echo "请再次尝试部署 $webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "导入已有证书" + + # 定义文件路径 + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. 输入证书 (ECC 和 RSA 证书开头都是 BEGIN CERTIFICATE) + echo "请粘贴 证书 (CRT/PEM) 内容 (按两次回车结束):" + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. 输入私钥 (兼容 RSA, ECC, PKCS#8) + echo "请粘贴 证书私钥 (Private Key) 内容 (按两次回车结束):" + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. 智能校验 + # 只要包含 "BEGIN CERTIFICATE" 和 "PRIVATE KEY" 即可通过 + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # 识别当前证书类型并显示 + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "检测到 ECC 证书已成功保存。" + else + echo "检测到 RSA 证书已成功保存。" + fi + auth_method="ssl_imported" + else + echo "错误:无效的证书或私钥格式!" + certs_status + fi + + ;; + 3) + send_stats "不带证书改用HTTP访问" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "退出申请" + exit + ;; + esac fi } @@ -1561,6 +1635,40 @@ add_yuming() { } +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "请输入访问/监听端口,回车默认使用 80: " access_port + access_port=${access_port:-80} + fi +} + + + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # 如果 access_port 为空,则跳过 + [ -z "$access_port" ] && return 0 + + # 删除所有 listen 行 + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # 在 server { 后插入新的 listen + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1679,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1688,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1635,7 +1724,7 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address @@ -1694,7 +1783,6 @@ web_cache() { send_stats "清理站点缓存" cf_purge_cache cd /home/web && docker compose restart - restart_redis } @@ -1776,7 +1864,7 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then CFmessage=" cf模式已开启" else CFmessage="" @@ -1847,6 +1935,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # 删除旧定义 + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # 生成插入内容 + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # 插入到 “Happy publishing” 之前 + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1990,19 +2115,11 @@ nginx_gzip() { web_security() { send_stats "LDNMP环境防御" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "服务器网站防御程序 ${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "服务器网站防御程序 ${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" echo "1. 安装防御程序" echo "------------------------" @@ -2024,11 +2141,16 @@ web_security() { case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,56 +2164,57 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null echo "Fail2Ban防御程序已卸载" + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) @@ -2104,14 +2227,14 @@ web_security() { wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status echo "已配置cloudflare模式,可在cf后台,站点-安全性-事件中查看拦截记录" @@ -2176,26 +2299,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { - -CONFIG_FILE="/home/web/nginx.conf" +check_ldnmp_mode() { -# 获取当前的 worker_processes 设置值 -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# 根据值设置模式信息 -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # 检查 MySQL 配置文件中是否包含 4096M + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info=" 高性能模式" + else + mode_info=" 标准模式" + fi @@ -2204,7 +2324,7 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" # 检查 zstd 是否开启且未被注释(整行以 zstd on; 开头) if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then @@ -2233,7 +2353,7 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear send_stats "优化LDNMP环境" @@ -2252,9 +2372,11 @@ web_optimization() { 1) send_stats "站点标准模式" - # nginx调优 - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf + # php调优 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2282,7 +2404,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced @@ -2293,8 +2414,10 @@ web_optimization() { send_stats "站点高性能模式" # nginx调优 - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf # php调优 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2321,7 +2444,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_web_server echo "LDNMP环境已设置成 高性能模式" @@ -2372,7 +2494,7 @@ web_optimization() { check_docker_app() { - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then check_docker="${gl_lv}已安装${gl_bai}" else check_docker="${gl_hui}未安装${gl_bai}" @@ -2383,7 +2505,7 @@ check_docker_app() { # check_docker_app() { -# if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then # check_docker="${gl_lv}已安装${gl_bai}" # else # check_docker="${gl_hui}未安装${gl_bai}" @@ -2423,54 +2545,61 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. 区域检查 + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # 获取容器的创建时间和镜像名称 + # 2. 获取本地镜像信息 local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) - - # 提取镜像仓库和标签 - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} + [[ -z "$container_info" ]] && return - # 默认标签为 latest - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" - - # 添加对官方镜像的支持 - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. 智能路由判断 + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- 场景 A: 镜像在 GitHub (ghcr.io) --- + # 提取仓库路径,例如 ghcr.io/onexru/oneimg -> onexru/oneimg + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # 注意:ghcr.io 的 API 比较复杂,通常最快的方法是查 GitHub Repo 的 Release + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- 场景 B: 特殊指定 (即便在 Docker Hub,也想通过 GitHub Release 判断) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # 从 Docker Hub API 获取镜像发布时间 - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- 场景 C: 标准 Docker Hub --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # 验证获取的时间 - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # 比较时间戳 - if [[ $container_created_ts -lt $last_updated_ts ]]; then + # 4. 时间戳对比 + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 @@ -2705,16 +2834,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2727,7 +2873,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2748,7 +2894,8 @@ while true; do read -e -p "请输入你的选择: " choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "输入应用对外服务端口,回车默认使用${docker_port}端口: " app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port @@ -2756,10 +2903,9 @@ while true; do install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id clear echo "$docker_name 已经安装完成" @@ -2773,8 +2919,8 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id clear echo "$docker_name 已经安装完成" @@ -2789,8 +2935,8 @@ while true; do docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" send_stats "卸载$docker_name" ;; @@ -2840,7 +2986,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2861,36 +3007,41 @@ docker_app_plus() { read -e -p "输入你的选择: " choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "输入应用对外服务端口,回车默认使用${docker_port}端口: " app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id + send_stats "$app_name 安装" ;; + 2) docker_app_update - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + add_app_id + send_stats "$app_name 更新" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_name 卸载" ;; + 5) echo "${docker_name}域名访问设置" send_stats "${docker_name}域名访问设置" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) echo "域名格式 example.com 不带https://" @@ -2940,7 +3091,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2949,7 +3100,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2959,7 +3110,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -3005,52 +3156,41 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx +} + +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}已安装${gl_bai}" + else + check_f2b_status="${gl_hui}未安装${gl_bai}" + fi } f2b_install_sshd() { - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf - else + fi + + if command -v apt &>/dev/null; then install rsyslog systemctl start rsyslog systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog fi - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } f2b_sshd() { @@ -3133,8 +3273,7 @@ send_stats "安装LDNMP环境" root_use clear echo -e "${gl_huang}LDNMP环境未安装,开始安装LDNMP环境...${gl_bai}" -check_disk_space 3 -check_port +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3150,8 +3289,7 @@ send_stats "安装nginx环境" root_use clear echo -e "${gl_huang}nginx未安装,开始安装nginx环境...${gl_bai}" -check_disk_space 1 -check_port +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3201,10 +3339,21 @@ ldnmp_web_on() { } nginx_web_on() { - clear - echo "您的 $webname 搭建好了!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + echo "您的 $webname 搭建好了!" + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3221,40 +3370,38 @@ ldnmp_wp() { fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# echo "数据库名: $dbname" -# echo "用户名: $dbuse" -# echo "密码: $dbusepasswd" -# echo "数据库地址: mysql" -# echo "表前缀: wp_" } + ldnmp_Proxy() { clear webname="反向代理-IP+端口" @@ -3267,21 +3414,43 @@ ldnmp_Proxy() { if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "请输入你的反代IP: " reverseproxy + read -e -p "请输入你的反代IP (回车默认本机IP 127.0.0.1): " reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then read -e -p "请输入你的反代端口: " port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3292,8 +3461,6 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" send_stats "安装$webname" echo "开始部署 $webname" @@ -3301,32 +3468,36 @@ ldnmp_Proxy_backend() { add_yuming fi - # 获取用户输入的多个IP:端口(用空格分隔) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then read -e -p "请输入你的多个反代IP+端口用空格隔开(例如 127.0.0.1:3000 127.0.0.1:3002): " reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # 动态生成 upstream 配置 upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # 替换模板中的占位符 sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3334,6 +3505,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "服务名" "通信类型" "本机地址" "后端地址" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # 服务名取文件名 + service_name=$(basename "$conf" .conf) + + # 获取 upstream 块中的 server 后端 IP:端口 + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # 获取 listen 端口 + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # 默认本地 IP + ip_address + local_ip="$ipv4_address" + + # 获取通信类型,优先从文件名后缀或内容判断 + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # 拼接监听 IP:端口 + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "Stream四层代理" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "Stream四层代理转发工具 $check_docker $update_status" + echo "NGINX Stream 是 NGINX 的 TCP/UDP 代理模块,用于实现高性能的 传输层流量转发和负载均衡。" + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. 安装 2. 更新 3. 卸载" + echo "------------------------" + echo "4. 添加转发服务 5. 修改转发服务 6. 删除转发服务" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "安装Stream四层代理" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "更新Stream四层代理" + ;; + 3) + read -e -p "确定要删除 nginx 容器吗?这可能会影响网站功能!(y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "更新Stream四层代理" + echo "nginx 容器已删除。" + else + echo "操作已取消。" + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "添加四层代理" + ;; + 5) + send_stats "编辑转发配置" + read -e -p "请输入你要编辑的服务名: " stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "修改四层代理" + ;; + 6) + send_stats "删除转发配置" + read -e -p "请输入你要删除的服务名: " stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "删除四层代理" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="Stream四层代理-负载均衡" + + send_stats "安装$webname" + echo "开始部署 $webname" + + # 获取代理名称 + read -rp "请输入代理转发名称 (如 mysql_proxy): " proxy_name + if [ -z "$proxy_name" ]; then + echo "名称不能为空"; return 1 + fi + + # 获取监听端口 + read -rp "请输入本机监听端口 (如 3306): " listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "端口必须是数字"; return 1 + fi + + echo "请选择协议类型:" + echo "1. TCP 2. UDP" + read -rp "请输入序号 [1-2]: " proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "无效选择"; return 1 ;; + esac + + read -e -p "请输入你的一个或者多个后端IP+端口用空格隔开(例如 10.13.0.2:3306 10.13.0.3:3306): " reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 动态添加/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "您的 $webname 搭建好了!" + echo "------------------------" + echo "访问地址:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3351,11 +3716,11 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear send_stats "LDNMP站点管理" @@ -3363,8 +3728,7 @@ ldnmp_web_status() { echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output} 证书到期时间" + echo -e "站点: ${output} 证书到期时间" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3375,9 +3739,28 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "数据库: ${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" @@ -3391,11 +3774,11 @@ ldnmp_web_status() { echo "" echo "操作" echo "------------------------" - echo "1. 申请/更新域名证书 2. 更换站点域名" + echo "1. 申请/更新域名证书 2. 克隆站点域名" echo "3. 清理站点缓存 4. 创建关联站点" echo "5. 查看访问日志 6. 查看错误日志" echo "7. 编辑全局配置 8. 编辑站点配置" - echo "9. 管理站点数据库 10. 查看站点分析报告" + echo "9. 管理站点数据库 10. 查看站点分析报告" echo "------------------------" echo "20. 删除指定站点数据" echo "------------------------" @@ -3407,30 +3790,26 @@ ldnmp_web_status() { send_stats "申请域名证书" read -e -p "请输入你的域名: " yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "更换站点域名" - echo -e "${gl_hong}强烈建议: ${gl_bai}先备份好全站数据再更换站点域名!" + send_stats "克隆站点域名" read -e -p "请输入旧域名: " oddyuming read -e -p "请输入新域名: " yuming install_certbot install_ssltls certs_status - # mysql替换 - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3441,18 +3820,15 @@ ldnmp_web_status() { done # 网站目录替换 - mv /home/web/html/$oddyuming /home/web/html/$yuming + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3513,7 +3889,7 @@ ldnmp_web_status() { 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3558,21 +3934,21 @@ while true; do install wget iptables_open panel_app_install - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id send_stats "${panelname}安装" ;; 2) panel_app_manage - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id send_stats "${panelname}控制" ;; 3) panel_app_uninstall - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt send_stats "${panelname}卸载" ;; *) @@ -3871,6 +4247,7 @@ frps_main_ports() { frps_panel() { send_stats "FRP服务端" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3901,8 +4278,8 @@ frps_panel() { install jq grep ss install_docker generate_frps_config - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP服务端已经安装完成" ;; 2) @@ -3911,8 +4288,8 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP服务端已经更新完成" ;; 3) @@ -3922,8 +4299,8 @@ frps_panel() { rm -rf /home/frp close_port 8055 8056 - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" ;; 5) @@ -3968,6 +4345,7 @@ frps_panel() { frpc_panel() { send_stats "FRP客户端" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do @@ -3997,8 +4375,8 @@ frpc_panel() { install jq grep ss install_docker configure_frpc - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP客户端已经安装完成" ;; 2) @@ -4007,8 +4385,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + + add_app_id echo "FRP客户端已经更新完成" ;; @@ -4018,8 +4396,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "应用已卸载" ;; @@ -4050,6 +4428,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4087,26 +4466,26 @@ yt_menu_pro() { send_stats "正在安装 yt-dlp..." echo "正在安装 yt-dlp..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id echo "安装完成。按任意键继续..." read ;; 2) send_stats "正在更新 yt-dlp..." echo "正在更新 yt-dlp..." - sudo yt-dlp -U - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + yt-dlp -U + + add_app_id echo "更新完成。按任意键继续..." read ;; 3) send_stats "正在卸载 yt-dlp..." echo "正在卸载 yt-dlp..." - sudo rm -f /usr/local/bin/yt-dlp - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "卸载完成。按任意键继续..." read ;; 5) @@ -4309,9 +4688,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4321,8 +4699,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4334,6 +4712,13 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } @@ -4378,7 +4763,9 @@ while true; do ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf + chattr +i /etc/resolv.conf send_stats "手动编辑DNS配置" ;; *) @@ -4538,6 +4925,7 @@ dd_xitong() { dd_xitong_1() { echo -e "重装后初始用户名: ${gl_huang}root${gl_bai} 初始密码: ${gl_huang}LeitboGi0ro${gl_bai} 初始端口: ${gl_huang}22${gl_bai}" + echo -e "${gl_huang}重装后请及时修改初始密码,防止暴力入侵。命令行输入passwd修改密码${gl_bai}" echo -e "按任意键继续..." read -n 1 -s -r -p "" install wget @@ -4571,10 +4959,12 @@ dd_xitong() { echo "重装系统" echo "--------------------------------" echo -e "${gl_hong}注意: ${gl_bai}重装有风险失联,不放心者慎用。重装预计花费15分钟,请提前备份数据。" - echo -e "${gl_hui}感谢MollyLau大佬和bin456789大佬的脚本支持!${gl_bai} " + echo -e "${gl_hui}感谢bin456789大佬和leitbogioro大佬的脚本支持!${gl_bai} " + echo -e "${gl_hui}bin456789项目地址: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro项目地址: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4590,39 +4980,42 @@ dd_xitong() { echo "35. openSUSE Tumbleweed 36. fnos飞牛公测版" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" echo "0. 返回上一级选单" echo "------------------------" read -e -p "请选择要重装的系统: " sys_choice case "$sys_choice" in + + 1) - send_stats "重装debian 12" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "重装debian 13" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "重装debian 11" + send_stats "重装debian 12" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "重装debian 10" + send_stats "重装debian 11" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "重装debian 9" + send_stats "重装debian 10" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; @@ -4784,7 +5177,6 @@ dd_xitong() { exit ;; - 41) send_stats "重装windows11" dd_xitong_2 @@ -4792,6 +5184,7 @@ dd_xitong() { reboot exit ;; + 42) dd_xitong_2 send_stats "重装windows10" @@ -4799,6 +5192,7 @@ dd_xitong() { reboot exit ;; + 43) send_stats "重装windows7" dd_xitong_4 @@ -4808,23 +5202,25 @@ dd_xitong() { ;; 44) - send_stats "重装windows server 22" + send_stats "重装windows server 25" dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "重装windows server 19" + send_stats "重装windows server 22" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "重装windows server 16" + send_stats "重装windows server 19" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; @@ -4917,7 +5313,6 @@ bbrv3() { echo "------------------------------------------------" echo "仅支持Debian/Ubuntu" echo "请备份数据,将为你升级Linux内核开启BBR3" - echo "VPS是512M内存的,请提前添加1G虚拟内存,防止因内存不足失联!" echo "------------------------------------------------" read -e -p "确定继续吗?(Y/N): " choice @@ -5119,7 +5514,7 @@ clamav_scan() { > /home/docker/clamav/log/scan.log > /dev/null 2>&1 # 执行 Docker 命令 - docker run -it --rm \ + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5654,7 +6049,10 @@ linux_trash() { done } - +linux_fav() { +send_stats "命令收藏夹" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} # 创建备份 create_backup() { @@ -6439,7 +6837,7 @@ rsync_manager() { -linux_ps() { +linux_info() { clear send_stats "系统信息查询" @@ -6490,43 +6888,47 @@ linux_ps() { local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" echo -e "系统信息查询" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}主机名: ${gl_bai}$hostname" - echo -e "${gl_kjlan}系统版本: ${gl_bai}$os_info" - echo -e "${gl_kjlan}Linux版本: ${gl_bai}$kernel_version" + echo -e "${gl_kjlan}主机名: ${gl_bai}$hostname" + echo -e "${gl_kjlan}系统版本: ${gl_bai}$os_info" + echo -e "${gl_kjlan}Linux版本: ${gl_bai}$kernel_version" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU架构: ${gl_bai}$cpu_arch" - echo -e "${gl_kjlan}CPU型号: ${gl_bai}$cpu_info" - echo -e "${gl_kjlan}CPU核心数: ${gl_bai}$cpu_cores" - echo -e "${gl_kjlan}CPU频率: ${gl_bai}$cpu_freq" + echo -e "${gl_kjlan}CPU架构: ${gl_bai}$cpu_arch" + echo -e "${gl_kjlan}CPU型号: ${gl_bai}$cpu_info" + echo -e "${gl_kjlan}CPU核心数: ${gl_bai}$cpu_cores" + echo -e "${gl_kjlan}CPU频率: ${gl_bai}$cpu_freq" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU占用: ${gl_bai}$cpu_usage_percent%" - echo -e "${gl_kjlan}系统负载: ${gl_bai}$load" - echo -e "${gl_kjlan}物理内存: ${gl_bai}$mem_info" - echo -e "${gl_kjlan}虚拟内存: ${gl_bai}$swap_info" - echo -e "${gl_kjlan}硬盘占用: ${gl_bai}$disk_info" + echo -e "${gl_kjlan}CPU占用: ${gl_bai}$cpu_usage_percent%" + echo -e "${gl_kjlan}系统负载: ${gl_bai}$load" + echo -e "${gl_kjlan}TCP|UDP连接数: ${gl_bai}$tcp_count|$udp_count" + echo -e "${gl_kjlan}物理内存: ${gl_bai}$mem_info" + echo -e "${gl_kjlan}虚拟内存: ${gl_bai}$swap_info" + echo -e "${gl_kjlan}硬盘占用: ${gl_bai}$disk_info" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}总接收: ${gl_bai}$rx" - echo -e "${gl_kjlan}总发送: ${gl_bai}$tx" + echo -e "${gl_kjlan}总接收: ${gl_bai}$rx" + echo -e "${gl_kjlan}总发送: ${gl_bai}$tx" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}网络算法: ${gl_bai}$congestion_algorithm $queue_algorithm" + echo -e "${gl_kjlan}网络算法: ${gl_bai}$congestion_algorithm $queue_algorithm" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}运营商: ${gl_bai}$isp_info" + echo -e "${gl_kjlan}运营商: ${gl_bai}$isp_info" if [ -n "$ipv4_address" ]; then - echo -e "${gl_kjlan}IPv4地址: ${gl_bai}$ipv4_address" + echo -e "${gl_kjlan}IPv4地址: ${gl_bai}$ipv4_address" fi if [ -n "$ipv6_address" ]; then - echo -e "${gl_kjlan}IPv6地址: ${gl_bai}$ipv6_address" + echo -e "${gl_kjlan}IPv6地址: ${gl_bai}$ipv6_address" fi - echo -e "${gl_kjlan}DNS地址: ${gl_bai}$dns_addresses" - echo -e "${gl_kjlan}地理位置: ${gl_bai}$country $city" - echo -e "${gl_kjlan}系统时间: ${gl_bai}$timezone $current_time" + echo -e "${gl_kjlan}DNS地址: ${gl_bai}$dns_addresses" + echo -e "${gl_kjlan}地理位置: ${gl_bai}$country $city" + echo -e "${gl_kjlan}系统时间: ${gl_bai}$timezone $current_time" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}运行时长: ${gl_bai}$runtime" + echo -e "${gl_kjlan}运行时长: ${gl_bai}$runtime" echo @@ -6551,7 +6953,7 @@ linux_tools() { echo -e "${gl_kjlan}11. ${gl_bai}btop 现代化监控工具 ${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}ranger 文件管理工具" echo -e "${gl_kjlan}13. ${gl_bai}ncdu 磁盘占用查看工具 ${gl_kjlan}14. ${gl_bai}fzf 全局搜索工具" echo -e "${gl_kjlan}15. ${gl_bai}vim 文本编辑器 ${gl_kjlan}16. ${gl_bai}nano 文本编辑器 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系统" + echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系统 ${gl_kjlan}18. ${gl_bai}opencode AI编程助手 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}黑客帝国屏保 ${gl_kjlan}22. ${gl_bai}跑火车屏保" echo -e "${gl_kjlan}26. ${gl_bai}俄罗斯方块小游戏 ${gl_kjlan}27. ${gl_bai}贪吃蛇小游戏" @@ -6710,6 +7112,17 @@ linux_tools() { send_stats "安装git" ;; + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "安装opencode" + ;; + + 21) clear install cmatrix @@ -6738,6 +7151,7 @@ linux_tools() { nsnake send_stats "安装nsnake" ;; + 28) clear install ninvaders @@ -6763,6 +7177,8 @@ linux_tools() { clear send_stats "全部卸载" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) @@ -6820,7 +7236,7 @@ linux_bbr() { send_stats "alpine开启bbr3" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6844,53 +7260,381 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # send_stats "docker管理" - echo -e "Docker管理" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}安装更新Docker环境 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局状态 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理 ${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}Docker镜像管理" - echo -e "${gl_kjlan}5. ${gl_bai}Docker网络管理" - echo -e "${gl_kjlan}6. ${gl_bai}Docker卷管理" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}7. ${gl_bai}清理无用的docker容器和镜像网络数据卷" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}8. ${gl_bai}更换Docker源" - echo -e "${gl_kjlan}9. ${gl_bai}编辑daemon.json文件" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}开启Docker-ipv6访问" - echo -e "${gl_kjlan}12. ${gl_bai}关闭Docker-ipv6访问" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}20. ${gl_bai}卸载Docker环境" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "请输入你的选择: " sub_choice + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' - case $sub_choice in - 1) - clear - send_stats "安装docker环境" - install_add_docker + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } - ;; - 2) - clear - local container_count=$(docker ps -a -q 2>/dev/null | wc -l) - local image_count=$(docker images -q 2>/dev/null | wc -l) - local network_count=$(docker network ls -q 2>/dev/null | wc -l) - local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}当前备份列表:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "无备份" + } - send_stats "docker全局状态" - echo "Docker版本" + + + # ---------------------------- + # 备份 + # ---------------------------- + backup_docker() { + send_stats "Docker备份" + + echo -e "${YELLOW}正在备份 Docker 容器...${NC}" + docker ps --format '{{.Names}}' + read -e -p "请输入要备份的容器名(多个空格分隔,回车备份全部运行中容器): " containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}没有找到容器${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# 自动生成的还原脚本" >> "$RESTORE_SCRIPT" + + # 记录已打包过的 Compose 项目路径,避免重复打包 + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}备份容器: $c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}检测到 $c 是 docker-compose 容器${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "未检测到 compose 目录,请手动输入路径: " project_dir + fi + + # 如果该 Compose 项目已经打包过,跳过 + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}Compose 项目 [$project_name] 已备份过,跳过重复打包...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose 恢复: $project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}Compose 项目 [$project_name] 已打包: ${project_dir}${NC}" + else + echo -e "${RED}未找到 docker-compose.yml,跳过此容器...${NC}" + fi + else + # 普通容器备份卷 + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "打包卷: $path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # 端口 + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # 环境变量 + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # 卷映射 + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # 镜像 + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# 还原容器: $c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # 备份 /home/docker 下的所有文件(不含子目录) + if [ -d "/home/docker" ]; then + echo -e "${BLUE}备份 /home/docker 下的文件...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}/home/docker 下的文件已打包到: ${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}备份完成: ${BACKUP_DIR}${NC}" + echo -e "${GREEN}可用还原脚本: ${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # 还原 + # ---------------------------- + restore_docker() { + + send_stats "Docker还原" + read -e -p "请输入要还原的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + + echo -e "${BLUE}开始执行还原操作...${NC}" + + install tar jq gzip + install_docker + + # --------- 优先还原 Compose 项目 --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "未找到原始路径,请输入还原目录路径: " original_path + + # 检查该 compose 项目的容器是否已经在运行 + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}Compose 项目 [$project_name] 已有容器在运行,跳过还原...${NC}" + continue + fi + + read -e -p "确认还原 Compose 项目 [$project_name] 到路径 [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "请输入新的还原路径: " original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}Compose 项目 [$project_name] 已解压到: $original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}Compose 项目 [$project_name] 还原完成!${NC}" + fi + done + + # --------- 继续还原普通容器 --------- + echo -e "${BLUE}检查并还原普通 Docker 容器...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}处理容器: $container${NC}" + + # 检查容器是否已经存在且正在运行 + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 已在运行,跳过还原...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}未找到镜像信息,跳过: $container${NC}"; continue; } + + # 端口映射 + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # 环境变量 + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # 卷映射 + 卷数据恢复 + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "恢复卷数据: $VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # 删除已存在但未运行的容器 + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 存在但未运行,删除旧容器...${NC}" + docker rm -f "$container" + fi + + # 启动容器 + echo "执行还原命令: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}未找到普通容器的备份信息${NC}" + + # 还原 /home/docker 下的文件 + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}正在还原 /home/docker 下的文件...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}/home/docker 下的文件已还原完成${NC}" + else + echo -e "${YELLOW}未找到 /home/docker 下文件的备份,跳过...${NC}" + fi + + + } + + + # ---------------------------- + # 迁移 + # ---------------------------- + migrate_docker() { + send_stats "Docker迁移" + install jq + read -e -p "请输入要迁移的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + + read -e -p "目标服务器IP: " TARGET_IP + read -e -p "目标服务器SSH用户名: " TARGET_USER + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}传输备份中...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # 使用密钥登录 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # 删除备份 + # ---------------------------- + delete_backup() { + send_stats "Docker备份文件删除" + read -e -p "请输入要删除的备份目录: " BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}备份目录不存在${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}已删除备份: ${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # 主菜单 + # ---------------------------- + main_menu() { + send_stats "Docker备份迁移还原" + while true; do + clear + echo "------------------------" + echo -e "Docker备份/迁移/还原工具" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. 备份docker项目" + echo -e "2. 迁移docker项目" + echo -e "3. 还原docker项目" + echo -e "4. 删除docker项目的备份文件" + echo "------------------------" + echo -e "0. 返回上一级菜单" + echo "------------------------" + read -e -p "请选择: " choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}无效选项${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "docker管理" + echo -e "Docker管理" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}安装更新Docker环境 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局状态 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}Docker镜像管理" + echo -e "${gl_kjlan}5. ${gl_bai}Docker网络管理" + echo -e "${gl_kjlan}6. ${gl_bai}Docker卷管理" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}7. ${gl_bai}清理无用的docker容器和镜像网络数据卷" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}8. ${gl_bai}更换Docker源" + echo -e "${gl_kjlan}9. ${gl_bai}编辑daemon.json文件" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}11. ${gl_bai}开启Docker-ipv6访问" + echo -e "${gl_kjlan}12. ${gl_bai}关闭Docker-ipv6访问" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}备份/迁移/还原Docker环境" + echo -e "${gl_kjlan}20. ${gl_bai}卸载Docker环境" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "请输入你的选择: " sub_choice + + case $sub_choice in + 1) + clear + send_stats "安装docker环境" + install_add_docker + + ;; + 2) + clear + local container_count=$(docker ps -a -q 2>/dev/null | wc -l) + local image_count=$(docker images -q 2>/dev/null | wc -l) + local network_count=$(docker network ls -q 2>/dev/null | wc -l) + local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + + send_stats "docker全局状态" + echo "Docker版本" docker -v docker compose version @@ -7076,6 +7820,9 @@ linux_docker() { restart docker ;; + + + 11) clear send_stats "Docker v6 开" @@ -7088,6 +7835,11 @@ linux_docker() { docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear send_stats "Docker卸载" @@ -7157,6 +7909,7 @@ linux_test() { echo -e "${gl_kjlan}综合性测试" echo -e "${gl_kjlan}31. ${gl_bai}bench 性能测试" echo -e "${gl_kjlan}32. ${gl_bai}spiritysdx 融合怪测评 ${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}nodequality 融合怪测评 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -7274,9 +8027,17 @@ linux_test() { 32) send_stats "spiritysdx融合怪测评" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "nodequality融合怪测评" + clear + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion @@ -7343,7 +8104,7 @@ linux_Oracle() { local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} # 运行Docker容器 - docker run -itd --name=lookbusy --restart=always \ + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ @@ -7411,7 +8172,8 @@ linux_Oracle() { 4) clear - echo "该功能处于开发阶段,敬请期待!" + send_stats "R探长开机脚本" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7441,6 +8203,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7458,20 +8223,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}环境已安装${gl_bai} $output $db_output" + echo -e "${gl_lv}环境已安装${gl_bai} 站点: $output 数据库: $db_output" fi fi @@ -7513,7 +8278,7 @@ linux_ldnmp() { echo -e "${gl_huang}23. ${gl_bai}站点反向代理-IP+端口 ${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}站点反向代理-域名" echo -e "${gl_huang}25. ${gl_bai}安装Bitwarden密码管理平台 ${gl_huang}26. ${gl_bai}安装Halo博客网站" echo -e "${gl_huang}27. ${gl_bai}安装AI绘画提示词生成器 ${gl_huang}28. ${gl_bai}站点反向代理-负载均衡" - echo -e "${gl_huang}30. ${gl_bai}自定义静态站点" + echo -e "${gl_huang}29. ${gl_bai}Stream四层代理转发 ${gl_huang}30. ${gl_bai}自定义静态站点" echo -e "${gl_huang}------------------------" echo -e "${gl_huang}31. ${gl_bai}站点数据管理 ${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}备份全站数据" echo -e "${gl_huang}33. ${gl_bai}定时远程备份 ${gl_huang}34. ${gl_bai}还原全站数据" @@ -7544,18 +8309,23 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7581,12 +8351,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7616,12 +8389,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7659,12 +8436,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7707,12 +8488,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7733,9 +8517,13 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp @@ -7758,12 +8546,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7796,13 +8588,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7832,12 +8627,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7966,12 +8764,15 @@ linux_ldnmp() { add_yuming read -e -p "请输入跳转域名: " reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -8003,12 +8804,14 @@ linux_ldnmp() { echo -e "域名格式: ${gl_huang}google.com${gl_bai}" read -e -p "请输入你的反代域名: " fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -8024,20 +8827,17 @@ linux_ldnmp() { send_stats "安装$webname" echo "开始部署 $webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8047,15 +8847,11 @@ linux_ldnmp() { send_stats "安装$webname" echo "开始部署 $webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; @@ -8066,11 +8862,13 @@ linux_ldnmp() { echo "开始部署 $webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8093,6 +8891,10 @@ linux_ldnmp() { ;; + 29) + stream_panel + ;; + 30) clear webname="静态站点" @@ -8101,11 +8903,13 @@ linux_ldnmp() { add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8170,6 +8974,8 @@ linux_ldnmp() { case "$choice" in [Yy]) read -e -p "请输入远端服务器IP: " remote_ip + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then echo "错误: 请输入远端服务器IP。" continue @@ -8178,7 +8984,7 @@ linux_ldnmp() { if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" echo "文件已传送至远程服务器home目录。" else echo "未找到要传送的文件。" @@ -8259,7 +9065,6 @@ linux_ldnmp() { echo -e "${gl_huang}正在解压 $filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot @@ -8383,7 +9188,6 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis send_stats "更新$ldnmp_pods" echo "更新${ldnmp_pods}完成" @@ -8396,7 +9200,6 @@ linux_ldnmp() { cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8454,19 +9257,30 @@ linux_ldnmp() { linux_panel() { +local sub_choice="$1" +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi +while true; do - - while true; do + if [ -z "$sub_choice" ]; then clear echo -e "应用市场" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") # 用循环设置颜色 - for i in {1..100}; do + for i in {1..150}; do if echo "$app_numbers" | grep -q "^$i$"; then declare "color$i=${gl_lv}" else @@ -8479,2359 +9293,3832 @@ linux_panel() { echo -e "${gl_kjlan}5. ${color5}OpenList多存储文件列表程序 ${gl_kjlan}6. ${color6}Ubuntu远程桌面网页版" echo -e "${gl_kjlan}7. ${color7}哪吒探针VPS监控面板 ${gl_kjlan}8. ${color8}QB离线BT磁力下载面板" echo -e "${gl_kjlan}9. ${color9}Poste.io邮件服务器程序 ${gl_kjlan}10. ${color10}RocketChat多人在线聊天系统" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}11. ${color11}禅道项目管理软件 ${gl_kjlan}12. ${color12}青龙面板定时任务管理平台" echo -e "${gl_kjlan}13. ${color13}Cloudreve网盘 ${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}简单图床图片管理程序" echo -e "${gl_kjlan}15. ${color15}emby多媒体管理系统 ${gl_kjlan}16. ${color16}Speedtest测速面板" echo -e "${gl_kjlan}17. ${color17}AdGuardHome去广告软件 ${gl_kjlan}18. ${color18}onlyoffice在线办公OFFICE" echo -e "${gl_kjlan}19. ${color19}雷池WAF防火墙面板 ${gl_kjlan}20. ${color20}portainer容器管理面板" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}21. ${color21}VScode网页版 ${gl_kjlan}22. ${color22}UptimeKuma监控工具" echo -e "${gl_kjlan}23. ${color23}Memos网页备忘录 ${gl_kjlan}24. ${color24}Webtop远程桌面网页版 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}25. ${color25}Nextcloud网盘 ${gl_kjlan}26. ${color26}QD-Today定时任务管理框架" echo -e "${gl_kjlan}27. ${color27}Dockge容器堆栈管理面板 ${gl_kjlan}28. ${color28}LibreSpeed测速工具" echo -e "${gl_kjlan}29. ${color29}searxng聚合搜索站 ${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrism私有相册系统" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}31. ${color31}StirlingPDF工具大全 ${gl_kjlan}32. ${color32}drawio免费的在线图表软件 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}33. ${color33}Sun-Panel导航面板 ${gl_kjlan}34. ${color34}Pingvin-Share文件分享平台" echo -e "${gl_kjlan}35. ${color35}极简朋友圈 ${gl_kjlan}36. ${color36}LobeChatAI聊天聚合网站" echo -e "${gl_kjlan}37. ${color37}MyIP工具箱 ${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}小雅alist全家桶" echo -e "${gl_kjlan}39. ${color39}Bililive直播录制工具 ${gl_kjlan}40. ${color40}webssh网页版SSH连接工具" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}41. ${color41}耗子管理面板 ${gl_kjlan}42. ${color42}Nexterm远程连接工具" echo -e "${gl_kjlan}43. ${color43}RustDesk远程桌面(服务端) ${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk远程桌面(中继端) ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}45. ${color45}Docker加速站 ${gl_kjlan}46. ${color46}GitHub加速站 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}47. ${color47}普罗米修斯监控 ${gl_kjlan}48. ${color48}普罗米修斯(主机监控)" echo -e "${gl_kjlan}49. ${color49}普罗米修斯(容器监控) ${gl_kjlan}50. ${color50}补货监控工具" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}51. ${color51}PVE开小鸡面板 ${gl_kjlan}52. ${color52}DPanel容器管理面板" echo -e "${gl_kjlan}53. ${color53}llama3聊天AI大模型 ${gl_kjlan}54. ${color54}AMH主机建站管理面板" echo -e "${gl_kjlan}55. ${color55}FRP内网穿透(服务端) ${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRP内网穿透(客户端) ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}57. ${color57}Deepseek聊天AI大模型 ${gl_kjlan}58. ${color58}Dify大模型知识库 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}59. ${color59}NewAPI大模型资产管理 ${gl_kjlan}60. ${color60}JumpServer开源堡垒机" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}61. ${color61}在线翻译服务器 ${gl_kjlan}62. ${color62}RAGFlow大模型知识库" echo -e "${gl_kjlan}63. ${color63}OpenWebUI自托管AI平台 ${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}it-tools工具箱" echo -e "${gl_kjlan}65. ${color65}n8n自动化工作流平台 ${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp视频下载工具" echo -e "${gl_kjlan}67. ${color67}ddns-go动态DNS管理工具 ${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL证书管理平台" echo -e "${gl_kjlan}69. ${color69}SFTPGo文件传输工具 ${gl_kjlan}70. ${color70}AstrBot聊天机器人框架" - echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}-------------------------" echo -e "${gl_kjlan}71. ${color71}Navidrome私有音乐服务器 ${gl_kjlan}72. ${color72}bitwarden密码管理器 ${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}73. ${color73}LibreTV私有影视 ${gl_kjlan}74. ${color74}MoonTV私有影视" echo -e "${gl_kjlan}75. ${color75}Melody音乐精灵 ${gl_kjlan}76. ${color76}在线DOS老游戏" echo -e "${gl_kjlan}77. ${color77}迅雷离线下载工具 ${gl_kjlan}78. ${color78}PandaWiki智能文档管理系统" echo -e "${gl_kjlan}79. ${color79}Beszel服务器监控 ${gl_kjlan}80. ${color80}linkwarden书签管理" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}81. ${color81}JitsiMeet视频会议" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet视频会议 ${gl_kjlan}82. ${color82}gpt-load高性能AI透明代理" + echo -e "${gl_kjlan}83. ${color83}komari服务器监控工具 ${gl_kjlan}84. ${color84}Wallos个人财务管理工具" + echo -e "${gl_kjlan}85. ${color85}immich图片视频管理器 ${gl_kjlan}86. ${color86}jellyfin媒体管理系统" + echo -e "${gl_kjlan}87. ${color87}SyncTV一起看片神器 ${gl_kjlan}88. ${color88}Owncast自托管直播平台" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox文件快递 ${gl_kjlan}90. ${color90}matrix去中心化聊天协议" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea私有代码仓库 ${gl_kjlan}92. ${color92}FileBrowser文件管理器" + echo -e "${gl_kjlan}93. ${color93}Dufs极简静态文件服务器 ${gl_kjlan}94. ${color94}Gopeed高速下载工具" + echo -e "${gl_kjlan}95. ${color95}paperless文档管理平台 ${gl_kjlan}96. ${color96}2FAuth自托管二步验证器" + echo -e "${gl_kjlan}97. ${color97}WireGuard组网(服务端) ${gl_kjlan}98. ${color98}WireGuard组网(客户端)" + echo -e "${gl_kjlan}99. ${color99}DSM群晖虚拟机 ${gl_kjlan}100. ${color100}Syncthing点对点文件同步工具" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI视频生成工具 ${gl_kjlan}102. ${color102}VoceChat多人在线聊天系统" + echo -e "${gl_kjlan}103. ${color103}Umami网站统计工具 ${gl_kjlan}104. ${color104}Stream四层代理转发工具" + echo -e "${gl_kjlan}105. ${color105}思源笔记 ${gl_kjlan}106. ${color106}Drawnix开源白板工具" + echo -e "${gl_kjlan}107. ${color107}PanSou网盘搜索 ${gl_kjlan}108. ${color108}LangBot聊天机器人" + echo -e "${gl_kjlan}109. ${color109}ZFile在线网盘 ${gl_kjlan}110. ${color110}Karakeep书签管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}多格式文件转换工具 ${gl_kjlan}112. ${color112}Lucky大内网穿透工具" + echo -e "${gl_kjlan}113. ${color113}Firefox浏览器" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}第三方应用列表" + echo -e "${gl_kjlan}想要让你的应用出现在这里?查看开发者指南: ${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # 获取应用描述 + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # 检查安装状态 (匹配 appno.txt 中的 ID) + # 这里假设 appno.txt 中记录的是 base_name (即文件名) + if echo "$app_numbers" | grep -q "^$base_name$"; then + # 如果已安装:显示 base_name - 描述 [已安装] (绿色) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text [已安装]${gl_bai}" + else + # 如果未安装:正常显示 + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done + + + + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}备份全部应用数据 ${gl_kjlan}r. ${gl_bai}还原全部应用数据" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "请输入你的选择: " sub_choice + fi - case $sub_choice in - 1) - - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" - - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } - - panel_app_manage() { - bt - } + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="宝塔面板" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_manage() { + bt + } - install_panel + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } + install_panel - ;; - 2) - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" + ;; + 2|aapanel) - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } - panel_app_manage() { - bt - } + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - install_panel + panel_app_manage() { + bt + } - ;; - 3) + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + install_panel - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + ;; + 3|1p|1panel) - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - panel_app_uninstall() { - 1pctl uninstall - } + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - install_panel + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - ;; - 4) + panel_app_uninstall() { + 1pctl uninstall + } - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + install_panel - docker_rum() { + ;; + 4|npm) - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 + docker_rum() { - } + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" - docker_app + } - ;; + local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" + local docker_url="官网介绍: https://nginxproxymanager.com/" + local docker_use="echo \"初始用户名: admin@example.com\"" + local docker_passwd="echo \"初始密码: changeme\"" + local app_size="1" - 5) + docker_app - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + ;; - docker_rum() { + 5|openlist) - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 - } + docker_rum() { + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 - ;; + } - 6) - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 + local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" + local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + } - } + local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" + local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + ;; + 7|nezha) + clear + send_stats "搭建哪吒" - ;; - 7) + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "搭建哪吒" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "哪吒监控 $check_docker $update_status" - echo "开源、轻量、易用的服务器监控与运维工具" - echo "官网搭建文档: https://nezha.wiki/guide/dashboard.html" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + echo -e "哪吒监控 $check_docker $update_status" + echo "开源、轻量、易用的服务器监控与运维工具" + echo "官网搭建文档: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. 使用" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1. 使用" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent离线BT磁力下载服务" + local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "搭建邮局" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "邮局服务 $check_docker $update_status" + echo "poste.io 是一个开源的邮件服务器解决方案," + echo "视频介绍: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "端口检测" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}端口 $port 当前可用${gl_bai}" + else + echo -e "${gl_hong}端口 $port 当前不可用${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "访问地址: " + echo "https://$yuming" + fi - 9) - send_stats "搭建邮局" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. 安装 2. 更新 3. 卸载" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice - clear - echo -e "邮局服务 $check_docker $update_status" - echo "poste.io 是一个开源的邮件服务器解决方案," - echo "视频介绍: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "请设置邮箱域名 例如 mail.yuming.com : " yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "先解析这些DNS记录" + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "按任意键继续..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "端口检测" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}端口 $port 当前可用${gl_bai}" - else - echo -e "${gl_hong}端口 $port 当前不可用${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then - yuming=$(cat /home/docker/mail.txt) - echo "访问地址: " + + add_app_id + + clear + echo "poste.io已经安装完成" + echo "------------------------" + echo "您可以使用以下地址访问poste.io:" echo "https://$yuming" - fi + echo "" - echo "------------------------" - echo "1. 安装 2. 更新 3. 卸载" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "请设置邮箱域名 例如 mail.yuming.com : " yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "先解析这些DNS记录" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "按任意键继续..." - read -n 1 -s -r -p "" + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i + yuming=$(cat /home/docker/mail.txt) + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.io已经安装完成" + echo "------------------------" + echo "您可以使用以下地址访问poste.io:" + echo "https://$yuming" + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "应用已卸载" + ;; - install jq - install_docker + *) + break + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + esac + break_end + done - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + ;; - clear - echo "poste.io已经安装完成" - echo "------------------------" - echo "您可以使用以下地址访问poste.io:" - echo "https://$yuming" - echo "" + 10|rocketchat) - ;; + local app_id="10" + local app_name="Rocket.Chat聊天系统" + local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," + local app_url="官方介绍: https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - echo "poste.io已经安装完成" - echo "------------------------" - echo "您可以使用以下地址访问poste.io:" - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt - echo "应用已卸载" - ;; + clear + ip_address + echo "已经安装完成" + check_docker_app_ip + } - *) - break - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "rocket.chat已经安装完成" + check_docker_app_ip + } - esac - break_end - done + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "应用已卸载" + } - ;; + docker_app_plus + ;; - 10) - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "已经安装完成" - check_docker_app_ip - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "rocket.chat已经安装完成" - check_docker_app_ip - } - - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "应用已卸载" - } - docker_app_plus - ;; + docker_rum() { + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + } - docker_rum() { + local docker_describe="禅道是通用的项目管理软件" + local docker_url="官网介绍: https://www.zentao.net/" + local docker_use="echo \"初始用户名: admin\"" + local docker_passwd="echo \"初始密码: 123456\"" + local app_size="2" + docker_app + ;; - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 + docker_rum() { - } - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - ;; - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 + } - docker_rum() { + local docker_describe="青龙面板是一个定时任务管理平台" + local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + 13|cloudreve) + + local app_id="13" + local app_name="cloudreve网盘" + local app_text="cloudreve是一个支持多家云存储的网盘系统" + local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - } - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "应用已卸载" + } - ;; - 13) + docker_app_plus + ;; - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest + } - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + local docker_describe="简单图床是一个简单的图床程序" + local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "应用已卸载" - } + docker_rum() { - docker_app_plus - ;; + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 - docker_rum() { + local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" + local docker_url="官网介绍: https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 - } + docker_rum() { - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + } + local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" + local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; + 17|adguardhome) - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 - } + docker_rum() { - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome - ;; - 17) - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 + } - docker_rum() { - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" + local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 18|onlyoffice) - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 - ;; + docker_rum() { + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver - 18) - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 + } - docker_rum() { + local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" + local docker_url="官网介绍: https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + ;; + 19|safeline) + send_stats "搭建雷池" - } + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "雷池服务 $check_docker" + echo "雷池是长亭科技开发的WAF站点防火墙程序面板,可以反代站点进行自动化防御" + echo "视频介绍: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + echo "------------------------" + echo "1. 安装 2. 更新 3. 重置密码 4. 卸载" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "输入你的选择: " choice - ;; + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - 19) - send_stats "搭建雷池" + add_app_id + clear + echo "雷池WAF面板已经安装完成" + check_docker_app_ip + docker exec safeline-mgt resetadmin - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "雷池服务 $check_docker" - echo "雷池是长亭科技开发的WAF站点防火墙程序面板,可以反代站点进行自动化防御" - echo "视频介绍: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" - if docker ps -a --format '{{.Names}}' | grep -q "$docker_name"; then + ;; + + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "雷池WAF面板已经更新完成" check_docker_app_ip - fi - echo "" + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "如果你是默认安装目录那现在项目已经卸载。如果你是自定义安装目录你需要到安装目录下自行执行:" + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer是一个轻量级的docker容器管理面板" + local docker_url="官网介绍: https://www.portainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode是一款强大的在线代码编写工具" + local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="Uptime Kuma 易于使用的自托管监控工具" + local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos是一款轻量级、自托管的备忘录中心" + local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" + local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" + local docker_url="官网介绍: https://nextcloud.com/" + local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" + local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="dockge是一个可视化的docker-compose容器管理面板" + local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" + local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng是一个私有且隐私的搜索引擎站点" + local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="photoprism非常强大的私有相册系统" + local docker_url="官网介绍: https://www.photoprism.app/" + local docker_use="echo \"账号: admin 密码: $rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" + local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" + local docker_url="官网介绍: https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" + local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" + local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" + local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" + local docker_url="官网介绍: ${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo \"账号: admin 密码: a123456\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" + local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" + local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "小雅全家桶" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" + local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="简易在线ssh连接工具和sftp工具" + local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="耗子面板" + local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" + local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" + local docker_url="官网介绍: https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" + local docker_url="官网介绍: https://rustdesk.com/zh-cn/" + local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" + local docker_url="官网介绍: https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" + local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="普罗米修斯监控" + local app_text="Prometheus+Grafana企业级监控系统" + local app_url="官网介绍: https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名密码均为: admin" + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "应用已卸载" + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" + local docker_url="官网介绍: https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" + local docker_url="官网介绍: https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" + local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE开小鸡" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" + local docker_url="官网介绍: https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMH面板" + local panelurl="官方地址: https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="Dify知识库" + local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" + local app_url="官方网站: https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "应用已卸载" + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="新一代大模型网关与AI资产管理系统" + local app_url="官方网站: https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer开源堡垒机" + local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" + local app_url="官方介绍: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名: admin" + echo "初始密码: ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "应用已更新" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "应用已卸载" + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" + local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow知识库" + local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" + local app_url="官方网站: https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" + local docker_url="官网介绍: https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" + local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="是一款功能强大的自动化工作流平台" + local docker_url="官网介绍: https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" + local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="开源免费的 SSL 证书自动化管理平台" + local docker_url="官网介绍: https://allinssl.com" + local docker_use="echo \"安全入口: /allinssl\"" + local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" + local docker_url="官网介绍: https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" + local docker_url="官网介绍: https://astrbot.app/" + local docker_use="echo \"用户名: astrbot 密码: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="是一个轻量、高性能的音乐流媒体服务器" + local docker_url="官网介绍: https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="一个你可以控制数据的密码管理器" + local docker_url="官网介绍: https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "设置LibreTV的登录密码: " app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="免费在线视频搜索与观看平台" + local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="moontv私有影视" + local app_text="免费在线视频搜索与观看平台" + local app_url="视频介绍: https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "设置登录用户名: " admin + read -e -p "设置登录用户密码: " admin_password + read -e -p "输入授权码: " shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "应用已卸载" + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 + + docker_rum() { + + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest + + + } + + local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" + local docker_url="官网介绍: https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + 76|dosgame) + + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 + + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest + + } + + local docker_describe="是一个中文DOS游戏合集网站" + local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + + + ;; - echo "------------------------" - echo "1. 安装 2. 更新 3. 重置密码 4. 卸载" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "输入你的选择: " choice + 77|xunlei) - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt - clear - echo "雷池WAF面板已经安装完成" - check_docker_app_ip - docker exec safeline-mgt resetadmin + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 - ;; + docker_rum() { - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - local app_no=$sub_choice - grep -qxF "${app_no}" /home/docker/appno.txt || echo "${app_no}" >> /home/docker/appno.txt - clear - echo "雷池WAF面板已经更新完成" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - local app_no=$sub_choice - sed -i "/\b${app_no}\b/d" /home/docker/appno.txt - echo "如果你是默认安装目录那现在项目已经卸载。如果你是自定义安装目录你需要到安装目录下自行执行:" - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; + read -e -p "设置登录用户名: " app_use + read -e -p "设置登录密码: " app_passwd - esac - break_end - done + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei - ;; + } - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 + local docker_describe="迅雷你的离线高速BT磁力下载工具" + local docker_url="官网介绍: https://github.com/cnk3x/xunlei" + local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer - } + 78|PandaWiki) - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" + local app_url="官方介绍: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" - ;; + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 + docker_app_update() { + docker_app_install + } - docker_rum() { + docker_app_uninstall() { + docker_app_install + } - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server + docker_app_plus + ;; - } - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + 79|beszel) + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 - docker_rum() { + docker_rum() { - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel - } + } + local docker_describe="Beszel轻量易用的服务器监控" + local docker_url="官网介绍: https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 - docker_rum() { + 80|linkwarden) - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + local app_id="80" + local app_name="linkwarden书签管理" + local app_text="一个开源的自托管书签管理平台,支持标签、搜索和团队协作。" + local app_url="官方网站: https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - } + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + # 下载官方 docker-compose 和 env 文件 + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 + # 生成随机密钥与密码 + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - docker_rum() { + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env + # 追加管理员账号信息 + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + # 启动容器 + docker compose up -d - } + clear + echo "已经安装完成" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # 保留原本的变量 + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "应用已卸载" + } + + docker_app_plus + ;; - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) - docker_rum() { + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet视频会议" + local app_text="一个开源的安全视频会议解决方案,支持多人在线会议、屏幕共享与加密通信。" + local app_url="官方网站: https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + docker_app_install() { - } + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + } - docker_rum() { + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + } - } + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "应用已卸载" + } - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + docker_app_plus - docker_rum() { + ;; - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge - } - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 82|gpt-load) - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - docker_rum() { + docker_rum() { - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest + read -e -p "设置${docker_name}的登录密钥(sk-开头字母和数字组合)如: sk-159kejilionyyds163: " app_passwd - } + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 + local docker_describe="高性能AI接口透明代理服务" + local docker_url="官网介绍: https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng - } - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 83|komari) - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - docker_rum() { + docker_rum() { - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - } + } + local docker_describe="轻量级的自托管服务器监控工具" + local docker_url="官网介绍: https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"默认账号: admin 默认密码: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 + 84|wallos) - docker_rum() { + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + docker_rum() { - } + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest + } - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="开源个人订阅追踪器,可用于财务管理" + local docker_url="官网介绍: https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 + ;; - docker_rum() { + 85|immich) - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + local app_id="85" + local app_name="immich图片视频管理器" + local app_text="高性能自托管照片和视频管理解决方案。" + local app_url="官网介绍: https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - } + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + docker compose up -d - docker_rum() { + clear + echo "已经安装完成" + check_docker_app_ip - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + } - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "应用已卸载" + } - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 + docker_app_plus - docker_rum() { - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } + ;; - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="官网介绍: ${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 86|jellyfin) + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 + docker_rum() { - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin - docker_rum() { + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + } - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + local docker_describe="是一款开源媒体服务器软件" + local docker_url="官网介绍: https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest - } + 87|synctv) + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 38) - send_stats "小雅全家桶" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv - 39) + } - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 - fi + local docker_describe="远程一起观看电影和直播的程序。它提供了同步观影、直播、聊天等功能" + local docker_url="官网介绍: https://github.com/synctv-org/synctv" + local docker_use="echo \"初始账号和密码: root 登陆后请及时修改登录密码\"" + local docker_passwd="" + local app_size="1" + docker_app - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + ;; - docker_rum() { - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + 88|owncast) - } + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 41) + } - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" + local docker_describe="开源、免费的自建直播平台" + local docker_url="官网介绍: https://owncast.online" + local docker_use="echo \"访问地址后面带 /admin 访问管理员页面\"" + local docker_passwd="echo \"初始账号: admin 初始密码: abc123 登陆后请及时修改登录密码\"" + local app_size="1" + docker_app - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } + ;; - panel_app_manage() { - panel-cli - } - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } - install_panel + 89|file-code-box) - ;; + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 + docker_rum() { - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest - docker_rum() { + } - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + local docker_describe="匿名口令分享文本和文件,像拿快递一样取文件" + local docker_url="官网介绍: https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"访问地址后面带 /#/admin 访问管理员页面\"" + local docker_passwd="echo \"管理员密码: FileCodeBox2023\"" + local app_size="1" + docker_app - } + ;; - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 - docker_rum() { - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs + 90|matrix) - } + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 + docker_rum() { - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + add_yuming - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate + fi - docker_rum() { + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + echo "创建初始用户或管理员。请设置以下内容用户名和密码以及是否为管理员。" + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - } + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker restart matrix - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker_rum() { + } - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + local docker_describe="Matrix是一个去中心化的聊天协议" + local docker_url="官网介绍: https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 - docker_rum() { + 91|gitea) - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest + local app_id="91" - } + local app_name="gitea私有代码仓库" + local app_text="免费新一代的代码托管平台,提供接近 GitHub 的使用体验。" + local app_url="视频介绍: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_install() { - 47) + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - docker_app_install() { - prometheus_install - clear - ip_address - echo "已经安装完成" - check_docker_app_ip - echo "初始用户名密码均为: admin" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "应用已卸载" + } - rm -rf /home/docker/monitoring - echo "应用已卸载" - } + docker_app_plus - docker_app_plus - ;; + ;; - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 - docker_rum() { - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + 92|filebrowser) - } + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - docker_rum() { + } - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true + local docker_describe="是一个基于Web的文件管理器" + local docker_url="官网介绍: https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 93|dufs) + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 + docker_rum() { - docker_rum() { + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest + } - } + local docker_describe="极简静态文件服务器,支持上传下载" + local docker_url="官网介绍: https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; + 94|gopeed) - 51) - clear - send_stats "PVE开小鸡" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 + docker_rum() { - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + read -e -p "设置登录用户名: " app_use + read -e -p "设置登录密码: " app_passwd - docker_rum() { + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite + } - } + local docker_describe="分布式高速下载工具,支持多种协议" + local docker_url="官网介绍: https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + 95|paperless) - } + local app_id="95" - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local app_name="paperless文档管理平台" + local app_text="开源的电子文档管理系统,它的主要用途是把你的纸质文件数字化并管理起来。" + local app_url="视频介绍: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" - 54) + docker_app_install() { - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env - panel_app_manage() { - panel_app_install - } + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - panel_app_uninstall() { - panel_app_install - } - install_panel - ;; + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } - 55) - frps_panel - ;; + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "应用已卸载" + } - 56) - frpc_panel - ;; + docker_app_plus - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + ;; - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama - } + 96|2fauth) - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local app_id="96" + local app_name="2FAuth自托管二步验证器" + local app_text="自托管的双重身份验证 (2FA) 账户管理和验证码生成工具。" + local app_url="官网: https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" + docker_app_install() { - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + add_yuming - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } - - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "应用已卸载" - } + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth - docker_app_plus + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml - ;; + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + clear + echo "已经安装完成" + check_docker_app_ip + } - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "应用已卸载" + } - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip + docker_app_plus - } + ;; - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "应用已卸载" - } - docker_app_plus - ;; + 97|wgs) + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - 60) + docker_rum() { - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" + read -e -p "请输入组网的客户端数量 (默认 5): " COUNT + COUNT=${COUNT:-5} + read -e -p "请输入 WireGuard 网段 (默认 10.13.13.0): " NETWORK + NETWORK=${NETWORK:-10.13.13.0} - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "已经安装完成" - check_docker_app_ip - echo "初始用户名: admin" - echo "初始密码: ChangeMe" - } + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) + ip link delete wg0 &>/dev/null - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "应用已更新" - } + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "应用已卸载" - } + sleep 3 - docker_app_plus - ;; + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " - docker_rum() { + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' - } + docker restart wireguard - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + sleep 2 + echo + echo -e "${gl_huang}所有客户端二维码配置: ${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}所有客户端配置代码: ${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}个客户端配置全部输出,使用方法如下:${gl_bai}" + echo -e "${gl_lv}1. 手机下载wg的APP,扫描上方二维码,可以快速连接网络${gl_bai}" + echo -e "${gl_lv}2. Windows下载客户端,复制配置代码连接网络。${gl_bai}" + echo -e "${gl_lv}3. Linux用脚本部署WG客户端,复制配置代码连接网络。${gl_bai}" + echo -e "${gl_lv}官方客户端下载方式: https://www.wireguard.com/install/${gl_bai}" + break_end + } + local docker_describe="现代化、高性能的虚拟专用网络工具" + local docker_url="官网介绍: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + ;; - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "已经安装完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "应用已卸载" - } + 98|wgc) - docker_app_plus + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 - ;; + docker_rum() { + mkdir -p /home/docker/wireguard/config/ - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - docker_rum() { + # 创建目录(如果不存在) + mkdir -p "$(dirname "$CONFIG_FILE")" - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + echo "请粘贴你的客户端配置,连续按两次回车保存:" - } + # 初始化变量 + input="" + empty_line_count=0 - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; + # 逐行读取用户输入 + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + # 写入配置文件 + echo "$input" > "$CONFIG_FILE" - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + echo "客户端配置已保存到 $CONFIG_FILE" - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ip link delete wg0 &>/dev/null + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + sleep 3 - docker_rum() { + docker logs wireguardc - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n + break_end - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" + } - } + local docker_describe="现代化、高性能的虚拟专用网络工具" + local docker_url="官网介绍: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 66) - yt_menu_pro - ;; + 99|dsm) - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + local app_id="99" - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local app_name="dsm群晖虚拟机" + local app_text="Docker容器中的虚拟DSM" + local app_url="官网: https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" - } + docker_app_install() { - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + read -e -p "设置 CPU 核数 (默认 2): " CPU_CORES + local CPU_CORES=${CPU_CORES:-2} - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + read -e -p "设置内存大小 (默认 4G): " RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml + + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 - docker_rum() { + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "应用已卸载" + } - } + docker_app_plus - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 - docker_rum() { + 100|syncthing) - mkdir -p /home/docker/astrbot/data + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - } + local docker_describe="开源的点对点文件同步工具,类似于 Dropbox、Resilio Sync,但完全去中心化。" + local docker_url="官网介绍: https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI视频生成工具" + local app_text="MoneyPrinterTurbo是一款使用AI大模型合成高清短视频的工具" + local app_url="官方网站: https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - docker_rum() { + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ - } + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "应用已卸载" + } + docker_app_plus - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + 102|vocechat) - } + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest + + } + + local docker_describe="是一款支持独立部署的个人云社交媒体聊天服务" + local docker_url="官网介绍: https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; - ;; + 103|umami) + local app_id="103" + local app_name="Umami网站统计工具" + local app_text="开源、轻量、隐私友好的网站分析工具,类似于GoogleAnalytics。" + local app_url="官方网站: https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - 73) + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + echo "初始用户名: admin" + echo "初始密码: umami" + } + + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "应用已卸载" + } - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 + docker_app_plus - docker_rum() { + ;; + + 104|nginx-stream) + stream_panel + ;; - read -e -p "设置LibreTV的登录密码: " app_passwd - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + 105|siyuan) - } + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + read -e -p "设置登录密码: " app_passwd + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - 74) + } - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + local docker_describe="思源笔记是一款隐私优先的知识管理系统" + local docker_url="官网介绍: https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - read -e -p "设置MoonTV的登录密码: " app_passwd - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest + 106|drawnix) - } + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix + } - 75) + local docker_describe="是一款强大的开源白板工具,集成思维导图、流程图等。" + local docker_url="官网介绍: https://github.com/plait-board/drawnix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 + ;; - docker_rum() { - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + 107|pansou) + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou是一个高性能的网盘资源搜索API服务。" + local docker_url="官网介绍: https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest - } + 108|langbot) + local app_id="108" + local app_name="LangBot聊天机器人" + local app_text="是一个开源的大语言模型原生即时通信机器人开发平台" + local app_url="官方网站: https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } - ;; + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - 77) + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "应用已卸载" + } - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 + docker_app_plus - docker_rum() { + ;; - read -e -p "设置${docker_name}的登录用户名: " app_use - read -e -p "设置${docker_name}的登录密码: " app_passwd - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + 109|zfile) - } + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - 78) + } - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + local docker_describe="是一个适用于个人或小团队的在线网盘程序。" + local docker_url="官网介绍: https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + ;; - docker_app_update() { - docker_app_install - } + 110|karakeep) + local app_id="110" + local app_name="karakeep书签管理" + local app_text="是一款可自行托管的书签应用,带有人工智能功能,专为数据囤积者而设计。" + local app_url="官方网站: https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker_app_uninstall() { - docker_app_install - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml - docker_app_plus - ;; + docker compose up -d + clear + echo "已经安装完成" + check_docker_app_ip + } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "应用已卸载" + } - 79) + docker_app_plus - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + ;; - docker_rum() { - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel - } + 111|convertx) - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - ;; + docker_rum() { + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} - 80) - local app_name="linkwarden书签管理" - local app_text="一个开源的自托管书签管理平台,支持标签、搜索和团队协作。" - local app_url="官方网站: https://linkwarden.app/" - local docker_name="linkwarden-linkwarden-1" - local docker_port="8080" - local app_size="3" + } - docker_app_install() { - install git openssl - mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden + local docker_describe="是一个功能强大的多格式文件转换工具(支持文档、图像、音频视频等)强烈建议添加域名访问" + local docker_url="项目地址: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - # 下载官方 docker-compose 和 env 文件 - curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml - curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" + ;; - # 生成随机密钥与密码 - local ADMIN_EMAIL="admin@example.com" - local ADMIN_PASSWORD=$(openssl rand -hex 8) - sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env - sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env - sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env - sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env + 112|lucky) - # 追加管理员账号信息 - echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env - echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # 由于 Lucky 使用 host 网络模式,这里的端口仅作记录/说明参考,实际由应用自身控制(默认16601) + local docker_port=8112 - sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + docker_rum() { - # 启动容器 - docker compose up -d + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - clear - echo "已经安装完成" - check_docker_app_ip + echo "正在等待 Lucky 初始化..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - } + } - docker_app_update() { - cd /home/docker/linkwarden && docker compose down --rmi all - curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml - curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" - - # 保留原本的变量 - source .env - mv .env.new .env - echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env - echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env - echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env - echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env - echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env - echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env - sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - - docker compose up -d - } + local docker_describe="Lucky 是一个大内网穿透及端口转发管理工具,支持 DDNS、反向代理、WOL 等功能。" + local docker_url="项目地址: https://github.com/gdy666/lucky" + local docker_use="echo \"默认账号密码: 666\"" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_uninstall() { - cd /home/docker/linkwarden && docker compose down --rmi all - rm -rf /home/docker/linkwarden - echo "应用已卸载" - } + ;; - docker_app_plus - ;; + 113|firefox) + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 + docker_rum() { - 81) - local app_name="JitsiMeet视频会议" - local app_text="一个开源的安全视频会议解决方案,支持多人在线会议、屏幕共享与加密通信。" - local app_url="官方网站: https://jitsi.org/" - local docker_name="jitsi" - local docker_port="8081" - local app_size="3" + read -e -p "设置登录密码: " admin_password - docker_app_install() { + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - add_yuming - mkdir -p /home/docker/jitsi && cd /home/docker/jitsi - wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) - unzip "$(ls -t | head -n 1)" - cd "$(ls -dt */ | head -n 1)" - cp env.example .env - ./gen-passwords.sh - mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} - sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env - sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env - docker compose up -d + local docker_describe="是一个运行在 Docker 中的 Firefox 浏览器,支持通过网页直接访问桌面版浏览器界面。" + local docker_url="项目地址: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" + ;; - } - docker_app_update() { - cd /home/docker/jitsi - cd "$(ls -dt */ | head -n 1)" - docker compose down --rmi all - docker compose up -d + b) + clear + send_stats "全部应用备份" - } + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}正在备份 $backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_app_uninstall() { - cd /home/docker/jitsi - cd "$(ls -dt */ | head -n 1)" - docker compose down --rmi all - rm -rf /home/docker/jitsi - echo "应用已卸载" - } + while true; do + clear + echo "备份文件已创建: /$backup_filename" + read -e -p "要传送备份数据到远程服务器吗?(Y/N): " choice + case "$choice" in + [Yy]) + read -e -p "请输入远端服务器IP: " remote_ip + read -e -p "目标服务器SSH端口 [默认22]: " TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - docker_app_plus + if [ -z "$remote_ip" ]; then + echo "错误: 请输入远端服务器IP。" + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "文件已传送至远程服务器/根目录。" + else + echo "未找到要传送的文件。" + fi + break + ;; + *) + echo "注意: 目前备份仅包含docker项目,不包含宝塔,1panel等建站面板的数据备份。" + break + ;; + esac + done - ;; + ;; + r) + root_use + send_stats "全部应用还原" + echo "可用的应用备份" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "回车键还原最新的备份,输入备份文件名还原指定的备份,输入0退出:" filename + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # 如果用户没有输入文件名,使用最新的压缩包 + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}正在解压 $filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "应用数据已还原,目前请手动进入指定应用菜单,更新应用,即可还原应用。" + else + echo "没有找到压缩包。" + fi + ;; - 0) - kejilion - ;; - *) - echo "无效的输入!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}错误: 未找到编号为 ${sub_choice} 的应用配置${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do @@ -11019,6 +13306,101 @@ linux_work() { +# 智能切换镜像源函数 +switch_mirror() { + # 可选参数,默认为 false + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # 获取用户国家 + local country + country=$(curl -s ipinfo.io/country) + + echo "检测到国家:$country" + + if [ "$country" = "CN" ]; then + echo "使用国内镜像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "使用官方镜像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "ssh防御" + while true; do + + check_f2b_status + echo -e "SSH防御程序 $check_f2b_status" + echo "fail2ban是一个SSH防止暴力破解工具" + echo "官网介绍: ${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. 安装防御程序" + echo "------------------------" + echo "2. 查看SSH拦截记录" + echo "3. 日志实时监控" + echo "------------------------" + echo "9. 卸载防御程序" + echo "------------------------" + echo "0. 返回上一级选单" + echo "------------------------" + read -e -p "请输入你的选择: " sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban防御程序已卸载" + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { @@ -11246,6 +13628,8 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root @@ -11261,13 +13645,14 @@ EOF clear echo "设置v4/v6优先级" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then echo -e "当前网络优先级设置: ${gl_huang}IPv4${gl_bai} 优先" else echo -e "当前网络优先级设置: ${gl_huang}IPv6${gl_bai} 优先" fi + echo "" echo "------------------------" echo "1. IPv4 优先 2. IPv6 优先 3. IPv6 修复工具" @@ -11278,12 +13663,10 @@ EOF case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "已切换为 IPv4 优先" - send_stats "已切换为 IPv4 优先" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 + rm -f /etc/gai.conf echo "已切换为 IPv6 优先" send_stats "已切换为 IPv6 优先" ;; @@ -11406,6 +13789,8 @@ EOF # 赋予新用户sudo权限 echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + install sudo + echo "操作已完成。" ;; @@ -11413,6 +13798,8 @@ EOF read -e -p "请输入用户名: " username # 赋予新用户sudo权限 echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) read -e -p "请输入用户名: " username @@ -11617,7 +14004,7 @@ EOF echo "选择更新源区域" echo "接入LinuxMirrors切换系统更新源" echo "------------------------" - echo "1. 中国大陆【默认】 2. 中国大陆【教育网】 3. 海外地区" + echo "1. 中国大陆【默认】 2. 中国大陆【教育网】 3. 海外地区 4. 智能切换更新源" echo "------------------------" echo "0. 返回上一级选单" echo "------------------------" @@ -11636,6 +14023,11 @@ EOF send_stats "海外源" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "智能切换更新源" + switch_mirror false false + ;; + *) echo "已取消" ;; @@ -11747,63 +14139,7 @@ EOF ;; 22) - root_use - send_stats "ssh防御" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH防御程序 $check_docker" - echo "fail2ban是一个SSH防止暴力破解工具" - echo "官网介绍: ${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1. 安装防御程序" - echo "------------------------" - echo "2. 查看SSH拦截记录" - echo "3. 日志实时监控" - echo "------------------------" - echo "9. 卸载防御程序" - echo "------------------------" - echo "0. 返回上一级选单" - echo "------------------------" - read -e -p "请输入你的选择: " sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2Ban防御程序已卸载" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; @@ -12052,15 +14388,15 @@ EOF 39) clear - send_stats "命令行历史记录" - bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) + linux_fav ;; 41) clear send_stats "留言板" - echo "科技lion留言板已迁移至官方社区!请在官方社区进行留言噢!" - echo "https://bbs.kejilion.pro/" + echo "访问科技lion官方留言板,您对脚本有任何想法欢迎留言交流!" + echo "https://board.kejilion.pro" + echo "公共密码: kejilion.sh" ;; 66) @@ -12070,16 +14406,18 @@ EOF echo "一条龙系统调优" echo "------------------------------------------------" echo "将对以下内容进行操作与优化" - echo "1. 更新系统到最新" + echo "1. 优化系统更新源,更新系统到最新" echo "2. 清理系统垃圾文件" echo -e "3. 设置虚拟内存${gl_huang}1G${gl_bai}" echo -e "4. 设置SSH端口号为${gl_huang}5522${gl_bai}" - echo -e "5. 开放所有端口" - echo -e "6. 开启${gl_huang}BBR${gl_bai}加速" - echo -e "7. 设置时区到${gl_huang}上海${gl_bai}" - echo -e "8. 自动优化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 国内: 223.5.5.5 ${gl_bai}" - echo -e "9. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10. Linux系统内核参数优化切换到${gl_huang}均衡优化模式${gl_bai}" + echo -e "5. 启动fail2ban防御SSH暴力破解" + echo -e "6. 开放所有端口" + echo -e "7. 开启${gl_huang}BBR${gl_bai}加速" + echo -e "8. 设置时区到${gl_huang}上海${gl_bai}" + echo -e "9. 自动优化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 国内: 223.5.5.5 ${gl_bai}" + echo -e "10. 设置网络为${gl_huang}ipv4优先${gl_bai}" + echo -e "11. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux系统内核参数优化切换到${gl_huang}均衡优化模式${gl_bai}" echo "------------------------------------------------" read -e -p "确定一键保养吗?(Y/N): " choice @@ -12088,58 +14426,54 @@ EOF clear send_stats "一条龙调优启动" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10. 更新系统到最新" + echo -e "[${gl_lv}OK${gl_bai}] 1/12. 更新系统到最新" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10. 清理系统垃圾文件" + echo -e "[${gl_lv}OK${gl_bai}] 2/12. 清理系统垃圾文件" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10. 设置虚拟内存${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 3/12. 设置虚拟内存${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10. 设置SSH端口号为${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 4/12. 设置SSH端口号为${gl_huang}5522${gl_bai}" echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10. 开放所有端口" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}] 5/12. 启动fail2ban防御SSH暴力破解" + + echo "------------------------------------------------" + echo -e "[${gl_lv}OK${gl_bai}] 6/12. 开放所有端口" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10. 开启${gl_huang}BBR${gl_bai}加速" + echo -e "[${gl_lv}OK${gl_bai}] 7/12. 开启${gl_huang}BBR${gl_bai}加速" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10. 设置时区到${gl_huang}上海${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 8/12. 设置时区到${gl_huang}上海${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10. 自动优化DNS地址${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}] 9/12. 自动优化DNS地址${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}] 10/12. 设置网络为${gl_huang}ipv4优先${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 11/12. 安装基础工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10. Linux系统内核参数优化" + echo -e "[${gl_lv}OK${gl_bai}] 12/12. Linux系统内核参数优化" echo -e "${gl_lv}一条龙系统调优已完成${gl_bai}" ;; @@ -12667,6 +15001,64 @@ echo "" +games_server_tools() { + + while true; do + clear + echo -e "游戏开服脚本合集" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}幻兽帕鲁开服脚本" + echo -e "${gl_kjlan}2. ${gl_bai}我的世界开服脚本" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}返回主菜单" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "请输入你的选择: " sub_choice + + case $sub_choice in + + 1) send_stats "幻兽帕鲁开服脚本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh + exit + ;; + 2) send_stats "我的世界开服脚本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/mc.sh ; chmod +x mc.sh ; ./mc.sh + exit + ;; + + 0) + kejilion + ;; + + *) + echo "无效的输入!" + ;; + esac + break_end + + done + + +} + + + + + + + + + + + + + + + + + + + + kejilion_update() { @@ -12787,8 +15179,7 @@ echo -e "${gl_kjlan}12. ${gl_bai}后台工作区" echo -e "${gl_kjlan}13. ${gl_bai}系统工具" echo -e "${gl_kjlan}14. ${gl_bai}服务器集群控制" echo -e "${gl_kjlan}15. ${gl_bai}广告专栏" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}幻兽帕鲁开服脚本" +echo -e "${gl_kjlan}16. ${gl_bai}游戏开服脚本合集" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}脚本更新" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -12797,7 +15188,7 @@ echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "请输入你的选择: " choice case $choice in - 1) linux_ps ;; + 1) linux_info ;; 2) clear ; send_stats "系统更新" ; linux_update ;; 3) clear ; send_stats "系统清理" ; linux_clean ;; 4) linux_tools ;; @@ -12814,10 +15205,7 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "幻兽帕鲁开服脚本" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; *) echo "无效的输入!" ;; @@ -12856,6 +15244,7 @@ echo "软件状态查看 k status sshd | k 状态 sshd " echo "软件开机启动 k enable docker | k autostart docke | k 开机启动 docker " echo "域名证书申请 k ssl" echo "域名证书到期查询 k ssl ps" +echo "docker管理平面 k docker" echo "docker环境安装 k docker install |k docker 安装" echo "docker容器管理 k docker ps |k docker 容器" echo "docker镜像管理 k docker img |k docker 镜像" @@ -12864,13 +15253,17 @@ echo "LDNMP缓存清理 k web cache" echo "安装WordPress k wp |k wordpress |k wp xxx.com" echo "安装反向代理 k fd |k rp |k 反代 |k fd xxx.com" echo "安装负载均衡 k loadbalance |k 负载均衡" +echo "安装L4负载均衡 k stream |k L4负载均衡" echo "防火墙面板 k fhq |k 防火墙" echo "开放端口 k dkdk 8080 |k 打开端口 8080" echo "关闭端口 k gbdk 7800 |k 关闭端口 7800" echo "放行IP k fxip 127.0.0.0/8 |k 放行IP 127.0.0.0/8" echo "阻止IP k zzip 177.5.25.36 |k 阻止IP 177.5.25.36" - - +echo "命令收藏夹 k fav | k 命令收藏夹" +echo "应用市场管理 k app" +echo "应用编号快捷管理 k app 26 | k app 1panel | k app npm" +echo "fail2ban管理 k fail2ban | k f2b" +echo "显示系统信息 k info" } @@ -12952,6 +15345,11 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift send_stats "快速设置虚拟内存" @@ -13002,6 +15400,10 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift send_stats "软件状态查看" @@ -13061,7 +15463,7 @@ else docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -13081,6 +15483,22 @@ else fi ;; + + app) + shift + send_stats "应用$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/kejilion_sh_log.txt b/kejilion_sh_log.txt index 634a8da6e..2945a0ab5 100644 --- a/kejilion_sh_log.txt +++ b/kejilion_sh_log.txt @@ -1249,5 +1249,158 @@ LDNMP建站flarum论坛安装时增加插件市场的安装,后期可以在后 应用市场新增Linkwarden书签管理器工具的安装及使用。 应用市场新增JitsiMeet视频会议具的安装及使用。 ------------------------ - +2025-08-10 v4.0.6 +系统工具重装系统新增Debian13的重装选项。Debian13 性能 安全 稳定全面提升。 +应用市场新增gpt-load高性能AI透明代理的安装及使用。 +应用市场新增komari服务器监控的安装及使用,平替哪吒监控。 +------------------------ +2025-08-13 v4.0.7 +应用市场新增Wallos个人财务管理工的安装及使用, +应用市场新增immich图片视频管理器的安装及使用, +应用市场新增jellyfin媒体管理系统的安装及使用, +应用市场新增SyncTV一起看片神器的安装及使用, +应用市场新增Owncast自托管直播平台的安装及使用, +------------------------ +2025-08-14 v4.0.8 +应用市场增加快速启动方式 命令行输入 k app 即可启动应用市场。 +应用市场增加应用编号快速启动 k app 13 就是13号应用启动,也可以输入应用名称启动 k app dpanel。 +支持远程命令安装和管理应用,bash <(curl -sL kejilion.sh) app moontv | bash <(curl -sL kejilion.sh) app 1panel。 +------------------------ +2025-08-18 v4.0.9 +应用市场增加全部应用数据备份和还原的功能。支持迁移到其他服务器的操作。 +-全部的应用备份还原不包含宝塔1panel等建站面板的数据。 +应用市场gpt-load安装时修改成自定义登录密钥。 +应用市场新增FileCodeBox文件快递的安装及使用。 +应用市场新增matrix去中心化聊天协议安装及使用。 +应用市场重构moontv,采用全新架构安装及使用。 +应用市场Ubuntu等远程桌面程序允许自定义用户名和密码进行安装及使用。 +------------------------ +2025-08-21 v4.0.10 +应用市场新增gitea私有代码仓库的安装及使用, +应用市场新增filebrowser文件管理器的安装及使用, +------------------------ +2025-08-24 v4.1.0 +docker管理增加全局备份还原迁移功能。 +修复部分应用的部署不成功问题, +------------------------ +2025-08-25 v4.1.1 +应用市场新增Dufs极简静态文件服务器的安装及使用。 +应用市场新增gopeed分布式高速下载工具的安装及使用。 +应用市场新增paperless文档管理平台的安装及使用。 +------------------------ +2025-08-27 v4.1.2 +应用市场新增WireGuard异地隧道组网工具的安装及使用。 +系统工具中一键重装系统新增Windows sreve 2025的安装。 +------------------------ +2025-09-03 v4.1.3 +应用市场尝试适配群晖系统文件结构。 +应用安装时的存储空间检测进行优化,可以更精准检测应用目录大小。 +应用市场新增2FAuth自托管二步验证器的安装及使用。 +系统工具IPV4和IPV6优先进行优化,不再粗暴关闭V6来实现V4优先了。 +------------------------ +2025-09-10 v4.1.4 +系统工具中DNS优化支持文件锁定功能,解决重启后文件复原问题。 +应用市场新增了DSM群晖虚拟机的安装及使用。 +系统工具中高级防火墙支持同时对多个国家地区的IP进行放行或封禁。 +系统工具中留言板功能重新上线,您对脚本有任何想法欢迎留言交流! +------------------------ +2025-09-15 v4.1.5 +k快捷键增加 k docker 命令行输入后能够快速到达docker管理平面。 +docker,站点等数据迁移时支持用户自定义输入SSH端口号迁移数据。 +k快捷命令增加了 k info 系统信息快速查询。 +------------------------ +2025-09-25 v4.1.6 +应用市场新增了Syncthing开源的点对点文件同步工具的安装及使用。 +甲骨文云合集中增加大佬的R探长开机脚本,非常感谢大佬脚本。 +又来修复SSH防御fail2ban加载ssh规则报错的问题。 +------------------------ +2025-09-30 v4.1.7 +应用市场新增了MoneyPrinterTurbo视频生成器的安装及使用。 +------------------------ +2025-10-06 v4.1.8 +应用市场FileCodeBox文件快递增加管理员入口的提示路径与密码。 +应用市场新增了VoceChat多人聊天系统的安装及使用。 +------------------------ +2025-10-09 v4.1.9 +LDNMP建站中将更换站点域名功能调整成克隆站点功能,这样可以保留老站点,让用户自己处决。 +应用市场新增了Umami网站统计工具的安装及使用。 +应用市场优化了部分应用因网络原因无法安装的问题。 +------------------------ +2025-10-21 v4.2.0 +LDNMP建站和应用市场新增nginx的stream四层代理转发工具。 +应用市场新增了思源笔记的安装及使用。 +应用市场新增了开源Drawnix白板工具的安装及使用。 +应用市场新增了PanSou网盘搜索工具的安装及使用。 +优化LDNMP环境中nginx将根据核心数优化并发连接数。 +------------------------ +2025-10-30 v4.2.1 +安装LDNMP/NGINX建站环境是检测网络进行dns优化IP优先调整,解决因网络问题无法安装环境的问题。 +国内安装docker环境时的加速站列表进行更新。 +应用市场中PanSou网盘搜索增加更多搜索源。 +------------------------ +2025-11-06 v4.2.2 +系统工具中一条龙优化功能新增自动ipv4优先, +系统工具中一条龙优化功能新增自动开启fail2ban防御SSH暴力破解。 +应用市场新增了LangBot开源聊天机器人的安装及使用。 +LDNMP安装环境时对mysql进行优化。 +------------------------ +2025-11-10 v4.2.3 +测试脚本合集中添加nodequality融合测试脚本。 +系统工具更换系统更新源新增智能切换更新源功能,识别国内自动切换华为源。 +------------------------ +2025-11-13 v4.2.4 +应用市场新增了karakeep书签管理的安装及使用。 +应用市场新增了zfile网盘的安装及使用。 +自动优化dns地址修复部分机型写入为空的问题。 +系统工具ssh防御修复个别系统安装后启动失败的问题。 +LDNMP环境中redis去除了不必要的清理机制。 +LDNMP环境NGINX环境优化安装流程,提升环境安装稳定性。 +------------------------ +2025-11-17 v4.2.5 +新增我的世界开服脚本工具,感谢阿卡林刘大佬进行适配,有我的世界开服需求的可以试试。 +主菜单新增游戏开服脚本合集,将幻兽帕鲁和我的世界的开服脚本加入合集。 +系统查询中添加TCP|UDP当前连接数显示。 +------------------------ +2025-11-19 v4.2.6 +安装docker环境采用更加成熟的linuxmirrors解决方案。提升安装兼容性和稳定性。 +系统工具一条龙优化增加了对系统源的优化,并将系统更新到最新。 +优化LDNMP环境中高性能模式无法切换的问题进行修复。 +LDNMP初始化时新增URL绑定,提升wordpress安装向导的稳定性。 +反向代理IP+端口功能优化,输入反代IP时回车可默认选择本机IP 127.0.0.1省去额外输入的麻烦。 +应用市场komari监控定义时区为上海,修复时间显示问题。 +------------------------ +2025-12-03 v4.2.7 +LDNMP建站为flarum论坛安装时增加了更多实用插件扩展。 +应用市场Dify知识库修复创建管理员出错的问题。官方API权限问题已擦屁股。 +对申请证书时80端口防火墙规则进行优化,提升申请证书成功率。 +------------------------ +2025-12-15 v4.2.8 +nginx反向代理优化,定义upstream和keepalive提升后端连接性能和稳定性。 +去掉docker自动化中无用的-it参数,提升运行稳定性,遵行最佳实践。 +添加kl快捷命令 k f2b 可以快速启动fail2ban管理工具。 +------------------------ +2025-12-19 v4.2.9 +nginx反向代理和负载均衡支持IP自定义监听端口功能,可实现反代内部IP加端口到网关的效果, +SSL申请失败后追加选项菜单,你可以继续申请,使用HTTP访问或者中断申请。 +应用市场新增了ConvertX全能文件转换工具的安装及使用。 +------------------------ +2025-12-24 v4.2.10 +SSL申请失败后追加导入已有证书选项,你可以导入域名有效证书使用了(如CF15年证书)。 +应用市场新增了lucky大内网反向代理工具的安装及使用。 +应用市场新增了Firefox浏览器的安装及使用。 +------------------------ +2025-12-25 v4.3.0 +应用市场支持第三方入驻功能,开发者可以将自己的项目加入到脚本中让大家使用。 +入驻指南: https://github.com/kejilion/sh/tree/main/apps +------------------------ +2026-01-06 v4.3.1 +应用市场应用发现新版本逻辑进行优化可以兼容github.io的新版本发现。 +应用市场memos拉取镜像源进行调整,采用官方更推荐的做法。 +应用市场优化部分项目的git更新机制,解决国内拉取卡顿的问题。 +基础工具中添加了目前流行的opencode编程AI助手可以在服务器上直接AI可视化开发编程。 +------------------------ +2026-01-13 v4.3.2 +对LDNMP站点和NGINX反代站点增加不停机续签域名SSL证书机制,老配置还是走端口申请证书。 +修复docker管理器无法进入容器的问题。 +------------------------ diff --git a/kr/kejilion.sh b/kr/kejilion.sh index 528d0abca..eecc5ec6f 100644 --- a/kr/kejilion.sh +++ b/kr/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.3" +sh_v="4.3.1" gl_hui='\e[37m' @@ -34,7 +34,7 @@ quanju_canshu -# 명령을 실행할 함수를 정의합니다 +# 명령을 실행하는 함수 정의 run_command() { if [ "$zhushi" -eq 0 ]; then "$@" @@ -57,9 +57,9 @@ CheckFirstRun_true() { -# 기능 매장 지점 정보를 수집하는 기능, 현재 스크립트 버전 번호, 사용 시간, 시스템 버전, CPU 아키텍처, 기계 국가 및 사용자가 사용하는 기능 이름을 기록합니다. 그들은 절대적으로 민감한 정보를 포함하지 않습니다. 제발 나를 믿으세요! -# 이 기능을 설계 해야하는 이유는 무엇입니까? 목적은 사용자가 사용하는 기능을 더 잘 이해하고 기능을 더욱 최적화하여 사용자 요구를 충족시키는 더 많은 기능을 시작하는 것입니다. -# 전체 텍스트의 경우 Send_Stats 기능 호출 위치, 투명 및 오픈 소스를 검색 할 수 있으며 우려 사항이 있으면 사용을 거부 할 수 있습니다. +# 이 기능은 함수에 묻혀있는 정보를 수집하고 사용자가 사용하는 현재 스크립트 버전 번호, 사용 시간, 시스템 버전, CPU 아키텍처, 시스템 국가 및 기능 이름을 기록합니다. 민감한 정보는 포함되어 있지 않으니 걱정하지 마세요! 저를 믿어주세요! +# 이 기능은 왜 설계되었나요? 그 목적은 사용자가 사용하고 싶어하는 기능을 더 잘 이해하고, 기능을 더욱 최적화하고 사용자 요구에 맞는 더 많은 기능을 출시하는 것입니다. +# send_stats 함수 호출 위치에 대한 전문을 검색할 수 있습니다. 투명하고 오픈 소스입니다. 불편하신 점이 있으시면 이용을 거부하실 수 있습니다. @@ -111,22 +111,22 @@ CheckFirstRun_false() { fi } -# 사용자에게 이용 약관에 동의하라는 메시지 +# 사용자에게 약관에 동의하라는 메시지를 표시합니다. UserLicenseAgreement() { clear - echo -e "${gl_kjlan}Tech Lion Script Toolbox에 오신 것을 환영합니다${gl_bai}" - echo "스크립트를 처음 사용하면 사용자 라이센스 계약을 읽고 동의하십시오." - echo "사용자 라이센스 계약 : https://blog.kejilion.pro/user-license-agreement/" + echo -e "${gl_kjlan}기술 사자 스크립트 도구 상자에 오신 것을 환영합니다${gl_bai}" + echo "스크립트를 처음 사용하는 경우 사용자 라이센스 계약을 읽고 동의하십시오." + echo "사용자 라이센스 계약: https://blog.kejilion.pro/user-license-agreement/" echo -e "----------------------" - read -r -p "위의 용어에 동의하십니까? (Y/N) :" user_input + read -r -p "위의 약관에 동의하십니까? (예/아니요):" user_input if [ "$user_input" = "y" ] || [ "$user_input" = "Y" ]; then - send_stats "라이센스 동의" + send_stats "라이센스 계약" sed -i 's/^permission_granted="false"/permission_granted="true"/' ~/kejilion.sh sed -i 's/^permission_granted="false"/permission_granted="true"/' /usr/local/bin/k else - send_stats "허가 거부" + send_stats "허가가 거부되었습니다" clear exit fi @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -170,13 +170,13 @@ ipv6_address=$(curl -s --max-time 1 https://v6.ipinfo.io/ip && echo) install() { if [ $# -eq 0 ]; then - echo "패키지 매개 변수는 제공되지 않습니다!" + echo "패키지 매개변수가 제공되지 않았습니다!" return 1 fi for package in "$@"; do if ! command -v "$package" &>/dev/null; then - echo -e "${gl_huang}설치$package...${gl_bai}" + echo -e "${gl_huang}설치 중$package...${gl_bai}" if command -v dnf &>/dev/null; then dnf -y update dnf install -y epel-release @@ -204,7 +204,7 @@ install() { pkg update pkg install -y "$package" else - echo "알 수없는 패키지 관리자!" + echo "알 수 없는 패키지 관리자입니다!" return 1 fi fi @@ -213,35 +213,45 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then - echo -e "${gl_huang}힌트:${gl_bai}불충분 한 디스크 공간!" - echo "현재 사용 가능한 공간 : $ ((uvery_space_mb/1024)) g" - echo "최소 수요 공간 :${required_gb}G" - echo "설치를 계속할 수 없습니다. 디스크 공간을 청소하고 다시 시도하십시오." - send_stats "불충분 한 디스크 공간" + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then + echo -e "${gl_huang}힌트:${gl_bai}디스크 공간이 부족합니다!" + echo "현재 사용 가능한 공간: $((available_space_mb/1024))G" + echo "최소 필요 공간:${required_gb}G" + echo "설치를 계속할 수 없습니다. 디스크 공간을 비운 후 다시 시도하십시오." + send_stats "디스크 공간이 부족합니다." break_end kejilion fi } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { if [ $# -eq 0 ]; then - echo "패키지 매개 변수는 제공되지 않습니다!" + echo "패키지 매개변수가 제공되지 않았습니다!" return 1 fi for package in "$@"; do - echo -e "${gl_huang}제거$package...${gl_bai}" + echo -e "${gl_huang}제거 중$package...${gl_bai}" if command -v dnf &>/dev/null; then dnf remove -y "$package" elif command -v yum &>/dev/null; then @@ -259,14 +269,14 @@ remove() { elif command -v pkg &>/dev/null; then pkg delete -y "$package" else - echo "알 수없는 패키지 관리자!" + echo "알 수 없는 패키지 관리자입니다!" return 1 fi done } -# 다양한 분포에 적합한 범용 SystemCTL 기능 +# 다양한 배포판에 적합한 범용 systemctl 기능 systemctl() { local COMMAND="$1" local SERVICE_NAME="$2" @@ -279,23 +289,23 @@ systemctl() { } -# 서비스를 다시 시작하십시오 +# 서비스 다시 시작 restart() { systemctl restart "$1" if [ $? -eq 0 ]; then echo "$1서비스가 다시 시작되었습니다." else - echo "오류 : 다시 시작합니다$1서비스가 실패했습니다." + echo "오류: 다시 시작$1서비스가 실패했습니다." fi } -# 서비스를 시작하십시오 +# 서비스 시작 start() { systemctl start "$1" if [ $? -eq 0 ]; then echo "$1서비스가 시작되었습니다." else - echo "오류 : 시작$1서비스가 실패했습니다." + echo "오류: 시작$1서비스가 실패했습니다." fi } @@ -303,19 +313,19 @@ start() { stop() { systemctl stop "$1" if [ $? -eq 0 ]; then - echo "$1서비스가 중단되었습니다." + echo "$1서비스가 중지되었습니다." else - echo "오류 : 중지$1서비스가 실패했습니다." + echo "오류: 중지$1서비스가 실패했습니다." fi } -# 서비스 상태를 확인하십시오 +# 서비스 상태 확인 status() { systemctl status "$1" if [ $? -eq 0 ]; then echo "$1서비스 상태가 표시됩니다." else - echo "오류 : 표시 할 수 없습니다$1서비스 상태." + echo "오류: 표시할 수 없습니다.$1서비스 상태." fi } @@ -328,14 +338,14 @@ enable() { /bin/systemctl enable "$SERVICE_NAME" fi - echo "$SERVICE_NAME전원 켜기로 설정합니다." + echo "$SERVICE_NAME부팅시 자동으로 시작되도록 설정되어 있습니다." } break_end() { - echo -e "${gl_lv}작업이 완료되었습니다${gl_bai}" - echo "계속하려면 키를 누르십시오 ..." + echo -e "${gl_lv}작업 완료${gl_bai}" + echo "계속하려면 아무 키나 누르세요..." read -n 1 -s -r -p "" echo "" clear @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,80 +417,40 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } install_add_docker() { - echo -e "${gl_huang}Docker 환경 설치 ...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + echo -e "${gl_huang}도커 환경 설치 중...${gl_bai}" + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -504,59 +474,59 @@ while true; do echo "도커 컨테이너 목록" docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" echo "" - echo "컨테이너 작동" + echo "컨테이너 운영" echo "------------------------" - echo "1. 새 컨테이너를 만듭니다" + echo "1. 새 컨테이너 생성" echo "------------------------" - echo "2. 지정된 컨테이너를 시작하십시오. 6. 모든 컨테이너를 시작하십시오" - echo "3. 지정된 컨테이너를 중지하십시오. 7. 모든 컨테이너를 중지하십시오" - echo "4. 지정된 컨테이너를 삭제합니다. 8. 모든 컨테이너를 삭제하십시오" - echo "5. 지정된 컨테이너를 다시 시작하십시오. 9. 모든 컨테이너를 다시 시작하십시오" + echo "2. 지정된 컨테이너 시작 6. 모든 컨테이너 시작" + echo "3. 지정된 컨테이너를 중지합니다. 7. 모든 컨테이너를 중지합니다." + echo "4. 지정된 컨테이너 삭제 8. 모든 컨테이너 삭제" + echo "5. 지정된 컨테이너를 다시 시작합니다. 9. 모든 컨테이너를 다시 시작합니다." echo "------------------------" - echo "11. 지정된 컨테이너를 입력하십시오. 12. 컨테이너 로그보기" - echo "13. 컨테이너 네트워크보기 14. 컨테이너 점유보기" + echo "11. 지정된 컨테이너를 입력합니다. 12. 컨테이너 로그를 봅니다." + echo "13. 컨테이너 네트워크 확인 14. 컨테이너 점유율 확인" echo "------------------------" - echo "15. 컨테이너 포트 액세스 켜기 16. 컨테이너 포트 액세스를 끄십시오." + echo "15. 컨테이너 포트 액세스 활성화 16. 컨테이너 포트 액세스 닫기" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "새 컨테이너를 만듭니다" - read -e -p "창조 명령을 입력하십시오 :" dockername + send_stats "새 컨테이너 만들기" + read -e -p "생성 명령을 입력하십시오:" dockername $dockername ;; 2) - send_stats "지정된 컨테이너를 시작하십시오" - read -e -p "컨테이너 이름 (공백별로 분리 된 여러 컨테이너 이름)을 입력하십시오." dockername + send_stats "지정된 컨테이너 시작" + read -e -p "컨테이너 이름을 입력하세요(여러 컨테이너 이름을 공백으로 구분하세요)." dockername docker start $dockername ;; 3) - send_stats "지정된 컨테이너를 중지하십시오" - read -e -p "컨테이너 이름 (공백별로 분리 된 여러 컨테이너 이름)을 입력하십시오." dockername + send_stats "지정된 컨테이너 중지" + read -e -p "컨테이너 이름을 입력하세요(여러 컨테이너 이름을 공백으로 구분하세요)." dockername docker stop $dockername ;; 4) - send_stats "지정된 컨테이너를 삭제하십시오" - read -e -p "컨테이너 이름 (공백별로 분리 된 여러 컨테이너 이름)을 입력하십시오." dockername + send_stats "지정된 컨테이너 삭제" + read -e -p "컨테이너 이름을 입력하세요(여러 컨테이너 이름을 공백으로 구분하세요)." dockername docker rm -f $dockername ;; 5) - send_stats "지정된 컨테이너를 다시 시작하십시오" - read -e -p "컨테이너 이름 (공백별로 분리 된 여러 컨테이너 이름)을 입력하십시오." dockername + send_stats "지정된 컨테이너를 다시 시작합니다." + read -e -p "컨테이너 이름을 입력하세요(여러 컨테이너 이름을 공백으로 구분하세요)." dockername docker restart $dockername ;; 6) - send_stats "모든 컨테이너를 시작하십시오" + send_stats "모든 컨테이너 시작" docker start $(docker ps -a -q) ;; 7) - send_stats "모든 컨테이너를 중지하십시오" + send_stats "모든 컨테이너 중지" docker stop $(docker ps -q) ;; 8) - send_stats "모든 컨테이너를 삭제하십시오" + send_stats "모든 컨테이너 삭제" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有容器吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -565,32 +535,32 @@ while true; do [Nn]) ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; 9) - send_stats "모든 컨테이너를 다시 시작하십시오" + send_stats "모든 컨테이너 다시 시작" docker restart $(docker ps -q) ;; 11) - send_stats "컨테이너를 입력하십시오" - read -e -p "컨테이너 이름을 입력하십시오 :" dockername - docker exec -it $dockername /bin/sh + send_stats "컨테이너를 입력하세요" + read -e -p "컨테이너 이름을 입력하세요:" dockername + docker exec $dockername /bin/sh break_end ;; 12) - send_stats "컨테이너 로그를 봅니다" - read -e -p "컨테이너 이름을 입력하십시오 :" dockername + send_stats "컨테이너 로그 보기" + read -e -p "컨테이너 이름을 입력하세요:" dockername docker logs $dockername break_end ;; 13) - send_stats "컨테이너 네트워크를 봅니다" + send_stats "컨테이너 네트워크 보기" echo "" container_ids=$(docker ps -q) echo "------------------------------------------------------------" - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "컨테이너 이름" "네트워크 이름" "IP 주소" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") local container_name=$(echo "$container_info" | awk '{print $1}') @@ -604,14 +574,14 @@ while true; do break_end ;; 14) - send_stats "컨테이너 점유를 봅니다" + send_stats "컨테이너 점유율 보기" docker stats --no-stream break_end ;; 15) - send_stats "컨테이너 포트 액세스를 허용합니다" - read -e -p "컨테이너 이름을 입력하십시오 :" docker_name + send_stats "컨테이너 포트 액세스 허용" + read -e -p "컨테이너 이름을 입력하세요:" docker_name ip_address clear_container_rules "$docker_name" "$ipv4_address" local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) @@ -620,8 +590,8 @@ while true; do ;; 16) - send_stats "컨테이너 포트 액세스 차단" - read -e -p "컨테이너 이름을 입력하십시오 :" docker_name + send_stats "컨테이너 포트 접근 차단" + read -e -p "컨테이너 이름을 입력하세요:" docker_name ip_address block_container_port "$docker_name" "$ipv4_address" local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) @@ -646,38 +616,38 @@ while true; do echo "" echo "미러 작동" echo "------------------------" - echo "1. 지정된 이미지 가져 오기 3. 지정된 이미지 삭제" + echo "1. 지정된 이미지 가져오기 3. 지정된 이미지 삭제" echo "2. 지정된 이미지 업데이트 4. 모든 이미지 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "거울을 당기십시오" - read -e -p "거울 이름을 입력하십시오 (공백으로 여러 거울 이름을 별도로 분리하십시오) :" imagenames + send_stats "이미지 가져오기" + read -e -p "이미지 이름을 입력하세요(여러 이미지 이름은 공백으로 구분하세요):" imagenames for name in $imagenames; do - echo -e "${gl_huang}이미지 얻기 :$name${gl_bai}" + echo -e "${gl_huang}이미지 가져오기:$name${gl_bai}" docker pull $name done ;; 2) - send_stats "이미지를 업데이트하십시오" - read -e -p "거울 이름을 입력하십시오 (공백으로 여러 거울 이름을 별도로 분리하십시오) :" imagenames + send_stats "이미지 업데이트" + read -e -p "이미지 이름을 입력하세요(여러 이미지 이름은 공백으로 구분하세요):" imagenames for name in $imagenames; do - echo -e "${gl_huang}업데이트 된 이미지 :$name${gl_bai}" + echo -e "${gl_huang}이미지 업데이트 중:$name${gl_bai}" docker pull $name done ;; 3) - send_stats "거울을 삭제하십시오" - read -e -p "거울 이름을 입력하십시오 (공백으로 여러 거울 이름을 별도로 분리하십시오) :" imagenames + send_stats "이미지 삭제" + read -e -p "이미지 이름을 입력하세요(여러 이미지 이름은 공백으로 구분하세요):" imagenames for name in $imagenames; do docker rmi -f $name done ;; 4) - send_stats "모든 이미지를 삭제합니다" + send_stats "모든 이미지 삭제" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有镜像吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -686,7 +656,7 @@ while true; do [Nn]) ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -754,16 +724,16 @@ install_crontab() { service cron start ;; *) - echo "지원되지 않는 분포 :$ID" + echo "지원되지 않는 배포판:$ID" return ;; esac else - echo "운영 체제를 결정할 수 없습니다." + echo "운영 체제를 확인할 수 없습니다." return fi - echo -e "${gl_lv}Crontab이 설치되고 Cron 서비스가 실행 중입니다.${gl_bai}" + echo -e "${gl_lv}crontab이 설치되어 있고 cron 서비스가 실행 중입니다.${gl_bai}" } @@ -775,27 +745,27 @@ docker_ipv6_on() { local CONFIG_FILE="/etc/docker/daemon.json" local REQUIRED_IPV6_CONFIG='{"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}' - # 구성 파일이 존재하는지 확인하고 파일을 작성하고 기본 설정이 존재하지 않는 경우 작성하십시오. + # 구성 파일이 있는지 확인하고, 없으면 파일을 생성하고 기본 설정을 씁니다. if [ ! -f "$CONFIG_FILE" ]; then echo "$REQUIRED_IPV6_CONFIG" | jq . > "$CONFIG_FILE" restart docker else - # JQ를 사용하여 구성 파일 업데이트를 처리하십시오 + # jq를 사용하여 구성 파일 업데이트 처리 local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # 현재 구성에 이미 IPv6 설정이 있는지 확인하십시오 + # 현재 구성에 이미 ipv6 설정이 있는지 확인하십시오. local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq '.ipv6 // false') - # 구성 업데이트 및 IPv6을 활성화하십시오 + # 구성 업데이트 및 IPv6 활성화 if [[ "$CURRENT_IPV6" == "false" ]]; then UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq '. + {ipv6: true, "fixed-cidr-v6": "2001:db8:1::/64"}') else UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq '. + {"fixed-cidr-v6": "2001:db8:1::/64"}') fi - # 원래 구성과 새로운 구성을 비교합니다 + # 원래 구성을 새 구성과 비교 if [[ "$ORIGINAL_CONFIG" == "$UPDATED_CONFIG" ]]; then - echo -e "${gl_huang}IPv6 액세스가 현재 활성화되어 있습니다${gl_bai}" + echo -e "${gl_huang}현재 IPv6 액세스가 활성화되어 있습니다.${gl_bai}" else echo "$UPDATED_CONFIG" | jq . > "$CONFIG_FILE" restart docker @@ -810,28 +780,28 @@ docker_ipv6_off() { local CONFIG_FILE="/etc/docker/daemon.json" - # 구성 파일이 있는지 확인하십시오 + # 구성 파일이 있는지 확인하십시오. if [ ! -f "$CONFIG_FILE" ]; then - echo -e "${gl_hong}구성 파일이 존재하지 않습니다${gl_bai}" + echo -e "${gl_hong}구성 파일이 존재하지 않습니다.${gl_bai}" return fi - # 현재 구성을 읽으십시오 + # 현재 구성 읽기 local ORIGINAL_CONFIG=$(<"$CONFIG_FILE") - # JQ를 사용하여 구성 파일 업데이트를 처리하십시오 + # jq를 사용하여 구성 파일 업데이트 처리 local UPDATED_CONFIG=$(echo "$ORIGINAL_CONFIG" | jq 'del(.["fixed-cidr-v6"]) | .ipv6 = false') - # 현재 IPv6 상태를 확인하십시오 + # 현재 ipv6 상태 확인 local CURRENT_IPV6=$(echo "$ORIGINAL_CONFIG" | jq -r '.ipv6 // false') - # 원래 구성과 새로운 구성을 비교합니다 + # 원래 구성을 새 구성과 비교 if [[ "$CURRENT_IPV6" == "false" ]]; then - echo -e "${gl_huang}IPv6 액세스는 현재 닫힙니다${gl_bai}" + echo -e "${gl_huang}IPv6 액세스는 현재 폐쇄되었습니다.${gl_bai}" else echo "$UPDATED_CONFIG" | jq . > "$CONFIG_FILE" restart docker - echo -e "${gl_huang}IPv6 액세스가 성공적으로 닫혔습니다${gl_bai}" + echo -e "${gl_huang}IPv6 액세스가 성공적으로 종료되었습니다.${gl_bai}" fi } @@ -870,117 +840,117 @@ iptables_open() { open_port() { local ports=($@) # 将传入的参数转换为数组 if [ ${#ports[@]} -eq 0 ]; then - echo "하나 이상의 포트 번호를 제공하십시오" + echo "포트 번호를 하나 이상 입력하세요." return 1 fi install iptables for port in "${ports[@]}"; do - # 기존 마감 규칙을 삭제하십시오 + # 기존 종료 규칙 삭제 iptables -D INPUT -p tcp --dport $port -j DROP 2>/dev/null iptables -D INPUT -p udp --dport $port -j DROP 2>/dev/null - # 열린 규칙을 추가하십시오 + # 공개 규칙 추가 if ! iptables -C INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j ACCEPT fi if ! iptables -C INPUT -p udp --dport $port -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -p udp --dport $port -j ACCEPT - echo "포트가 열렸습니다$port" + echo "포트가 열렸습니다.$port" fi done save_iptables_rules - send_stats "포트가 열렸습니다" + send_stats "포트가 열렸습니다." } close_port() { local ports=($@) # 将传入的参数转换为数组 if [ ${#ports[@]} -eq 0 ]; then - echo "하나 이상의 포트 번호를 제공하십시오" + echo "포트 번호를 하나 이상 입력하세요." return 1 fi install iptables for port in "${ports[@]}"; do - # 기존 열린 규칙을 삭제합니다 + # 기존 공개 규칙 삭제 iptables -D INPUT -p tcp --dport $port -j ACCEPT 2>/dev/null iptables -D INPUT -p udp --dport $port -j ACCEPT 2>/dev/null - # 가까운 규칙을 추가하십시오 + # 종료 규칙 추가 if ! iptables -C INPUT -p tcp --dport $port -j DROP 2>/dev/null; then iptables -I INPUT 1 -p tcp --dport $port -j DROP fi if ! iptables -C INPUT -p udp --dport $port -j DROP 2>/dev/null; then iptables -I INPUT 1 -p udp --dport $port -j DROP - echo "포트 폐쇄$port" + echo "항구 폐쇄$port" fi done - # 기존 규칙 삭제 (있는 경우) + # 기존 규칙 삭제(있는 경우) iptables -D INPUT -i lo -j ACCEPT 2>/dev/null iptables -D FORWARD -i lo -j ACCEPT 2>/dev/null - # 새로운 규칙을 먼저 삽입하십시오 + # 첫 번째 규칙에 새 규칙을 삽입합니다. iptables -I INPUT 1 -i lo -j ACCEPT iptables -I FORWARD 1 -i lo -j ACCEPT save_iptables_rules - send_stats "포트 폐쇄" + send_stats "항구 폐쇄" } allow_ip() { local ips=($@) # 将传入的参数转换为数组 if [ ${#ips[@]} -eq 0 ]; then - echo "하나 이상의 IP 주소 또는 IP 세그먼트를 제공하십시오." + echo "IP 주소 또는 IP 세그먼트를 하나 이상 입력하세요." return 1 fi install iptables for ip in "${ips[@]}"; do - # 기존 차단 규칙을 삭제하십시오 + # 기존 차단 규칙 삭제 iptables -D INPUT -s $ip -j DROP 2>/dev/null - # 허용 규칙을 추가하십시오 + # 허용 규칙 추가 if ! iptables -C INPUT -s $ip -j ACCEPT 2>/dev/null; then iptables -I INPUT 1 -s $ip -j ACCEPT - echo "IP 출시$ip" + echo "공개된 IP$ip" fi done save_iptables_rules - send_stats "IP 출시" + send_stats "공개된 IP" } block_ip() { local ips=($@) # 将传入的参数转换为数组 if [ ${#ips[@]} -eq 0 ]; then - echo "하나 이상의 IP 주소 또는 IP 세그먼트를 제공하십시오." + echo "IP 주소 또는 IP 세그먼트를 하나 이상 입력하세요." return 1 fi install iptables for ip in "${ips[@]}"; do - # 기존 허용 규칙을 삭제합니다 + # 기존 허용 규칙 삭제 iptables -D INPUT -s $ip -j ACCEPT 2>/dev/null - # 차단 규칙을 추가하십시오 + # 차단 규칙 추가 if ! iptables -C INPUT -s $ip -j DROP 2>/dev/null; then iptables -I INPUT 1 -s $ip -j DROP - echo "IP 차단$ip" + echo "IP가 차단됨$ip" fi done save_iptables_rules - send_stats "IP 차단" + send_stats "IP가 차단됨" } @@ -990,7 +960,7 @@ block_ip() { enable_ddos_defense() { - # 방어 DDO를 켜십시오 + # DDoS 보호 켜기 iptables -A DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT iptables -A DOCKER-USER -p tcp --syn -j DROP iptables -A DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT @@ -1000,12 +970,12 @@ enable_ddos_defense() { iptables -A INPUT -p udp -m limit --limit 3000/s -j ACCEPT iptables -A INPUT -p udp -j DROP - send_stats "DDOS 방어를 켜십시오" + send_stats "DDoS 방어 켜기" } -# DDOS 방어를 끕니다 +# DDoS 방어 끄기 disable_ddos_defense() { - # 방어 DDO를 끄십시오 + # DDoS 보호 끄기 iptables -D DOCKER-USER -p tcp --syn -m limit --limit 500/s --limit-burst 100 -j ACCEPT 2>/dev/null iptables -D DOCKER-USER -p tcp --syn -j DROP 2>/dev/null iptables -D DOCKER-USER -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null @@ -1015,7 +985,7 @@ disable_ddos_defense() { iptables -D INPUT -p udp -m limit --limit 3000/s -j ACCEPT 2>/dev/null iptables -D INPUT -p udp -j DROP 2>/dev/null - send_stats "DDOS 방어를 끕니다" + send_stats "DDoS 방어 끄기" } @@ -1025,91 +995,84 @@ disable_ddos_defense() { # 국가 IP 규칙을 관리하는 기능 manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # IPSET가 존재하지 않는 경우 작성하십시오 - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # IP 영역 파일을 다운로드하십시오 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "오류 : 다운로드$country_codeIP 영역 파일이 실패했습니다" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # IPSET에 IP를 추가하십시오 - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "오류: 다운로드$country_codeIP 영역 파일 실패" + continue + fi - # iptables와 함께 IP를 차단하십시오 - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "성공적으로 차단되었습니다$country_codeIP 주소" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # 허용 국가에 대한 IPSET 만들기 (존재하지 않는 경우) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "성공적으로 차단되었습니다$country_codeIP 주소" + rm "${country_code,,}.zone" + ;; - # IP 영역 파일을 다운로드하십시오 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "오류 : 다운로드$country_codeIP 영역 파일이 실패했습니다" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 기존 국가 규칙을 삭제합니다 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "오류: 다운로드$country_codeIP 영역 파일 실패" + continue + fi - # IPSET에 IP를 추가하십시오 - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # 지정된 국가의 IP 만 허용됩니다 - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "성공적으로 만 허용됩니다$country_codeIP 주소" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # 국가의 iptables 규칙을 삭제하십시오 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "허용되었습니다.$country_codeIP 주소" + rm "${country_code,,}.zone" + ;; - # ipset을 파괴하십시오 - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "성공적으로 해제했습니다$country_codeIP 주소 제한" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "성공적으로 제거되었습니다$country_codeIP 주소 제한" + ;; + + *) + echo "사용법: prepare_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables @@ -1123,35 +1086,35 @@ iptables_panel() { echo "" echo "방화벽 관리" echo "------------------------" - echo "1. 지정된 포트 2를 엽니 다. 지정된 포트를 닫으십시오." - echo "3. 모든 포트를 엽니 다. 4. 모든 포트를 닫으십시오" + echo "1. 지정 포트 열기 2. 지정 포트 닫기" + echo "3. 모든 포트를 엽니다. 4. 모든 포트를 닫습니다." echo "------------------------" echo "5. IP 화이트리스트 6. IP 블랙리스트" - echo "7. 지정된 IP를 지우십시오" + echo "7. 지정된 IP 지우기" echo "------------------------" - echo "11. 핑 허용 12. 핑을 비활성화하십시오" + echo "11. PING 허용 12. PING 비활성화" echo "------------------------" - echo "13. DDOS 방어 시작 14. DDOS 방어를 끄십시오" + echo "13. DDOS 방어 시작 14. DDOS 방어 끄기" echo "------------------------" - echo "15. 지정된 국가 IP 16. 지정된 국가 IP 만 허용됩니다." - echo "17. 지정된 국가에서 IP 제한을 해제합니다" + echo "15. 특정 국가 IP 차단 16. 특정 국가 IP만 허용" + echo "17. 지정된 국가에서 IP 제한을 해제합니다." echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - read -e -p "열린 포트 번호를 입력하십시오 :" o_port + read -e -p "열려 있는 포트 번호를 입력하세요." o_port open_port $o_port - send_stats "지정된 포트를 엽니 다" + send_stats "지정된 포트 열기" ;; 2) - read -e -p "닫힌 포트 번호를 입력하십시오 :" c_port + read -e -p "닫힌 포트 번호를 입력하세요:" c_port close_port $c_port - send_stats "지정된 포트를 닫습니다" + send_stats "지정된 포트 닫기" ;; 3) - # 모든 포트를 엽니 다 + # 모든 포트 열기 current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') iptables -F iptables -X @@ -1164,10 +1127,10 @@ iptables_panel() { iptables -A FORWARD -i lo -j ACCEPT iptables -A INPUT -p tcp --dport $current_port -j ACCEPT iptables-save > /etc/iptables/rules.v4 - send_stats "모든 포트를 엽니 다" + send_stats "모든 포트 열기" ;; 4) - # 모든 포트를 닫습니다 + # 모든 포트를 닫으세요 current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') iptables -F iptables -X @@ -1180,40 +1143,40 @@ iptables_panel() { iptables -A FORWARD -i lo -j ACCEPT iptables -A INPUT -p tcp --dport $current_port -j ACCEPT iptables-save > /etc/iptables/rules.v4 - send_stats "모든 포트를 닫습니다" + send_stats "모든 포트를 닫으세요" ;; 5) # IP 화이트리스트 - read -e -p "릴리스하려면 IP 또는 IP 세그먼트를 입력하십시오." o_ip + read -e -p "허용된 IP 또는 IP 세그먼트를 입력하세요." o_ip allow_ip $o_ip ;; 6) # IP 블랙리스트 - read -e -p "차단 된 IP 또는 IP 세그먼트를 입력하십시오." c_ip + read -e -p "차단된 IP 또는 IP 범위를 입력하세요." c_ip block_ip $c_ip ;; 7) - # 지정된 IP를 지우십시오 - read -e -p "청산 된 IP를 입력하십시오 :" d_ip + # 지정된 IP 지우기 + read -e -p "삭제된 IP를 입력하세요:" d_ip iptables -D INPUT -s $d_ip -j ACCEPT 2>/dev/null iptables -D INPUT -s $d_ip -j DROP 2>/dev/null iptables-save > /etc/iptables/rules.v4 - send_stats "지정된 IP를 지우십시오" + send_stats "지정된 IP 지우기" ;; 11) - # 핑을 허용하십시오 + # 핑 허용 iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT iptables-save > /etc/iptables/rules.v4 - send_stats "핑을 허용하십시오" + send_stats "핑 허용" ;; 12) - # 핑을 비활성화합니다 + # 핑 비활성화 iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT 2>/dev/null iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT 2>/dev/null iptables-save > /etc/iptables/rules.v4 - send_stats "핑을 비활성화합니다" + send_stats "핑 비활성화" ;; 13) enable_ddos_defense @@ -1223,20 +1186,20 @@ iptables_panel() { ;; 15) - read -e -p "차단 된 국가 코드 (예 : CN, US, JP)를 입력하십시오." country_code + read -e -p "차단된 국가 코드를 입력하세요(여러 국가 코드는 CN US JP와 같이 공백으로 구분될 수 있음)." country_code manage_country_rules block $country_code - send_stats "허용 국가$country_codeIP" + send_stats "국가 허용$country_codeIP" ;; 16) - read -e -p "허용 된 국가 코드 (예 : CN, US, JP)를 입력하십시오." country_code + read -e -p "허용되는 국가 코드를 입력하십시오(여러 국가 코드는 CN US JP와 같이 공백으로 구분할 수 있음)." country_code manage_country_rules allow $country_code - send_stats "나라를 차단하십시오$country_codeIP" + send_stats "블록 국가$country_codeIP" ;; 17) - read -e -p "청산 된 국가 코드 (예 : CN, US, JP)를 입력하십시오." country_code + read -e -p "삭제된 국가 코드를 입력하십시오(여러 국가 코드는 CN US JP와 같이 공백으로 구분될 수 있음)." country_code manage_country_rules unblock $country_code - send_stats "나라를 정리하십시오$country_codeIP" + send_stats "명확한 국가$country_codeIP" ;; *) @@ -1252,28 +1215,26 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 - # 현재 시스템에서 모든 스왑 파티션을 얻으십시오 + # 현재 시스템의 모든 스왑 파티션을 가져옵니다. local swap_partitions=$(grep -E '^/dev/' /proc/swaps | awk '{print $1}') - # 모든 스왑 파티션을 반복하고 삭제하십시오 + # 모든 스왑 파티션을 탐색하고 삭제합니다. for partition in $swap_partitions; do swapoff "$partition" wipefs -a "$partition" mkswap -f "$partition" done - # /swapfile이 더 이상 사용되지 않도록하십시오 + # /swapfile이 더 이상 사용되지 않는지 확인하세요. swapoff /swapfile - # 이전 /스왑 파일을 삭제하십시오 + # 이전 /swap 파일 삭제 rm -f /swapfile - # 새 스왑 파티션을 만듭니다 + # 새로운 스왑 파티션 생성 fallocate -l ${new_swap}M /swapfile chmod 600 /swapfile mkswap /swapfile @@ -1288,7 +1249,7 @@ add_swap() { rc-update add local fi - echo -e "가상 메모리 크기가 크기가 커졌습니다${gl_huang}${new_swap}${gl_bai}M" + echo -e "가상 메모리 크기가 다음과 같이 조정되었습니다.${gl_huang}${new_swap}${gl_bai}M" } @@ -1298,7 +1259,7 @@ check_swap() { local swap_total=$(free -m | awk 'NR==3{print $2}') -# 가상 메모리를 만들어야하는지 확인하십시오 +# 가상 메모리를 만들어야 하는지 확인 [ "$swap_total" -gt 0 ] || add_swap 1024 @@ -1314,21 +1275,21 @@ local swap_total=$(free -m | awk 'NR==3{print $2}') ldnmp_v() { - # nginx 버전을 얻으십시오 + # nginx 버전 받기 local nginx_version=$(docker exec nginx nginx -v 2>&1) local nginx_version=$(echo "$nginx_version" | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e "nginx : ${gl_huang}v$nginx_version${gl_bai}" - # MySQL 버전을 얻으십시오 + # mysql 버전 받기 local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local mysql_version=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SELECT VERSION();" 2>/dev/null | tail -n 1) echo -n -e " mysql : ${gl_huang}v$mysql_version${gl_bai}" - # PHP 버전을 얻으십시오 + # PHP 버전 받기 local php_version=$(docker exec php php -v 2>/dev/null | grep -oP "PHP \K[0-9]+\.[0-9]+\.[0-9]+") echo -n -e " php : ${gl_huang}v$php_version${gl_bai}" - # Redis 버전을 얻으십시오 + # Redis 버전 받기 local redis_version=$(docker exec redis redis-server -v 2>&1 | grep -oP "v=+\K[0-9]+\.[0-9]+") echo -e " redis : ${gl_huang}v$redis_version${gl_bai}" @@ -1341,20 +1302,18 @@ ldnmp_v() { install_ldnmp_conf() { - # 필요한 디렉토리 및 파일을 만듭니다 - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + # 필요한 디렉토리 및 파일 생성 + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl - # docker-compose.yml 파일을 다운로드하여 교체하십시오 + # docker-compose.yml 파일을 다운로드하여 교체하세요. wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml dbrootpasswd=$(openssl rand -base64 16) ; dbuse=$(openssl rand -hex 4) ; dbusepasswd=$(openssl rand -base64 8) - # docker-compose.yml 파일로 교체하십시오 + # docker-compose.yml 파일에서 교체 sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "stream" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # 국가 코드(예: CN, US 등)를 가져옵니다. + local country=$(curl -s ipinfo.io/country) + + # 국가에 따라 DNS 설정 + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "IPv4 우선순위로 전환됨" +send_stats "IPv4 우선순위로 전환됨" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,8 +1392,16 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # MySQL 튜닝 + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear echo "LDNMP 환경이 설치되었습니다" @@ -1416,19 +1421,26 @@ install_certbot() { local cron_job="0 0 * * * ~/auto_cert_renewal.sh" crontab -l 2>/dev/null | grep -vF "$cron_job" | crontab - (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "갱신 작업이 업데이트되었습니다" + echo "갱신 작업이 업데이트되었습니다." } + + + + + + + install_ssltls() { - docker stop nginx > /dev/null 2>&1 check_port > /dev/null 2>&1 + docker stop nginx > /dev/null 2>&1 cd ~ local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1450,10 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1451,15 +1466,15 @@ install_ssltls() { install_ssltls_text() { - echo -e "${gl_huang}$yuming공개 키 정보${gl_bai}" + echo -e "${gl_huang}$yuming공개키 정보${gl_bai}" cat /etc/letsencrypt/live/$yuming/fullchain.pem echo "" echo -e "${gl_huang}$yuming개인 키 정보${gl_bai}" cat /etc/letsencrypt/live/$yuming/privkey.pem echo "" echo -e "${gl_huang}인증서 저장 경로${gl_bai}" - echo "공개 키 :/etc/letsencrypt/live/$yuming/fullchain.pem" - echo "개인 키 :/etc/letsencrypt/live/$yuming/privkey.pem" + echo "공개 키: /etc/letsencrypt/live/$yuming/fullchain.pem" + echo "개인 키: /etc/letsencrypt/live/$yuming/privkey.pem" echo "" } @@ -1468,14 +1483,14 @@ install_ssltls_text() { add_ssl() { -echo -e "${gl_huang}SSL 인증서를 신속하게 신청하고 만료 전에 서명을 자동으로 갱신하십시오.${gl_bai}" +echo -e "${gl_huang}SSL 인증서를 빠르게 신청하고 만료되기 전에 자동으로 갱신하세요.${gl_bai}" yuming="${1:-}" if [ -z "$yuming" ]; then add_yuming fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1484,7 +1499,7 @@ ssl_ps ssl_ps() { - echo -e "${gl_huang}응용 인증서 만료${gl_bai}" + echo -e "${gl_huang}신청한 인증서의 만료 상태${gl_bai}" echo "사이트 정보 인증서 만료 시간" echo "------------------------" for cert_dir in /etc/letsencrypt/live/*; do @@ -1524,22 +1539,87 @@ certs_status() { local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ -f "$file_path" ]; then - send_stats "도메인 이름 인증서에 대한 성공적인 응용 프로그램" + send_stats "도메인 이름 인증서 신청이 성공했습니다." else - send_stats "도메인 이름 인증서 신청에 실패했습니다" - echo -e "${gl_hong}알아채다:${gl_bai}인증서 응용 프로그램이 실패했습니다. 가능한 이유를 확인하고 다시 시도하십시오." - echo -e "1. 도메인 이름 철자 오류 ➠ 도메인 이름이 올바르게 입력되었는지 확인하십시오." - echo -e "2. DNS 해상도 문제 ➠ 도메인 이름 이이 서버 IP로 올바르게 해결되었는지 확인합니다." - echo -e "3. 네트워크 구성 문제 ➠ CloudFlare Warp 및 기타 가상 네트워크를 사용하는 경우 임시로 종료하십시오." - echo -e "4. 방화벽 제한 ➠ 검증에 액세스 할 수 있도록 포트 80/443이 열려 있는지 확인" - echo -e "5. 응용 프로그램 수는 한계를 초과합니다. ➠ 암호화하자는 주간 제한 (5 배/도메인 이름/주)을 갖습니다." - echo -e "6. 국내 등록 제한 ➠ 도메인 이름이 중국 본토에 등록되어 있는지 확인하십시오." - break_end - clear - echo "다시 배포를 시도하십시오$webname" - add_yuming - install_ssltls - certs_status + send_stats "도메인 이름 인증서 신청 실패" + echo -e "${gl_hong}알아채다:${gl_bai}인증서 신청이 실패했습니다. 다음 가능한 이유를 확인하고 다시 시도하십시오." + echo -e "1. 도메인 이름이 잘못 입력되었습니다. ➠ 도메인 이름이 올바르게 입력되었는지 확인하세요." + echo -e "2. DNS 확인 문제 ➠ 도메인 이름이 서버 IP로 올바르게 확인되었는지 확인" + echo -e "3. 네트워크 구성 문제 ➠ Cloudflare Warp 등 가상 네트워크를 사용하는 경우 일시적으로 종료하세요." + echo -e "4. 방화벽 제한사항 ➠ 포트 80/443이 열려 있는지 확인하고 접근이 가능한지 확인하세요." + echo -e "5. 신청 횟수가 한도를 초과했습니다. ➠ Let's Encrypt에는 주간 한도(5회/도메인 이름/주)가 있습니다." + echo -e "6. 국내 등록 제한 ➠ 중국 ​​본토 환경의 경우 도메인 이름 등록 여부를 확인하시기 바랍니다." + echo "------------------------" + echo "1. 다시 적용 2. 기존 인증서 가져오기 3. 인증서 없이 HTTP 액세스 사용 0. 종료" + echo "------------------------" + read -e -p "선택사항을 입력하세요:" sub_choice + case $sub_choice in + 1) + send_stats "재신청" + echo "다시 배포해 보세요.$webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "기존 인증서 가져오기" + + # 파일 경로 정의 + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. 인증서를 입력합니다(ECC 및 RSA 인증서 모두 BEGIN CERTIFICATE로 시작함). + echo "인증서(CRT/PEM) 콘텐츠를 붙여넣으세요(종료하려면 Enter를 두 번 누르세요)." + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. 개인 키를 입력하세요. (RSA, ECC, PKCS#8과 호환 가능) + echo "인증서 개인 키(개인 키) 내용을 붙여넣으세요(종료하려면 Enter를 두 번 누르세요)." + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. 지능형 검증 + # 통과하려면 "BEGIN CERTIFICATE" 및 "PRIVATE KEY"만 포함하면 됩니다. + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # 현재 인증서 유형을 식별하고 표시합니다. + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "ECC 인증서가 성공적으로 저장되었음을 감지했습니다." + else + echo "RSA 인증서가 성공적으로 저장되었음을 감지했습니다." + fi + auth_method="ssl_imported" + else + echo "오류: 잘못된 인증서 또는 개인 키 형식입니다!" + certs_status + fi + + ;; + 3) + send_stats "인증서 없이 HTTP 액세스로 전환" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "신청철회" + exit + ;; + esac fi } @@ -1556,11 +1636,45 @@ fi add_yuming() { ip_address - echo -e "먼저 도메인 이름을 로컬 IP로 해결합니다.${gl_huang}$ipv4_address $ipv6_address${gl_bai}" - read -e -p "IP 또는 해결 된 도메인 이름을 입력하십시오." yuming + echo -e "먼저 도메인 이름을 로컬 IP로 확인합니다.${gl_huang}$ipv4_address $ipv6_address${gl_bai}" + read -e -p "귀하의 IP 또는 확인된 도메인 이름을 입력하십시오:" yuming +} + + +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "액세스/수신 포트를 입력하고 Enter를 눌러 기본적으로 80을 사용하십시오." access_port + access_port=${access_port:-80} + fi } + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # access_port가 비어 있으면 건너뛰세요. + [ -z "$access_port" ] && return 0 + + # 모든 청취 라인 제거 + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # 서버 { 뒤에 새 수신 대기 삽입 + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1685,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1694,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1635,17 +1730,17 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address check_docker_app_ip - echo "로그인 정보 :" - echo "사용자 이름 :$dbuse" + echo "로그인 정보:" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" echo - send_stats "시작$ldnmp_pods" + send_stats "시작하다$ldnmp_pods" } @@ -1655,29 +1750,29 @@ cf_purge_cache() { local EMAIL local ZONE_IDS - # 구성 파일이 있는지 확인하십시오 + # 구성 파일이 있는지 확인하십시오. if [ -f "$CONFIG_FILE" ]; then - # 구성 파일에서 API_TOKE 및 ZONE_ID를 읽으십시오 + # 구성 파일에서 API_TOKEN 및 zone_id를 읽습니다. read API_TOKEN EMAIL ZONE_IDS < "$CONFIG_FILE" - # Zone_ids를 배열로 변환합니다 + # ZONE_IDS를 어레이로 변환 ZONE_IDS=($ZONE_IDS) else - # 캐시 청소 여부를 사용자에게 프롬프트합니다 - read -e -p "CloudFlare의 캐시를 청소해야합니까? (Y/N) :" answer + # 캐시를 지울지 여부를 사용자에게 묻습니다. + read -e -p "Cloudflare의 캐시를 지워야 합니까? (예/아니요):" answer if [[ "$answer" == "y" ]]; then - echo "CF 정보가 저장됩니다$CONFIG_FILE, 나중에 CF 정보를 수정할 수 있습니다" - read -e -p "API_Token을 입력하십시오 :" API_TOKEN - read -e -p "CF 사용자 이름을 입력하십시오 :" EMAIL - read -e -p "Zone_ID를 입력하십시오 (공백으로 여러 차례 분리) :" -a ZONE_IDS + echo "CF 정보는 다음 위치에 저장됩니다.$CONFIG_FILE, 나중에 CF 정보를 수정할 수 있습니다." + read -e -p "API_TOKEN을 입력하세요:" API_TOKEN + read -e -p "CF 사용자 이름을 입력하세요:" EMAIL + read -e -p "zone_id를 입력하십시오(여러 개는 공백으로 구분)." -a ZONE_IDS mkdir -p /home/web/config/ echo "$API_TOKEN $EMAIL ${ZONE_IDS[*]}" > "$CONFIG_FILE" fi fi - # 각 Zone_ID를 루프하고 CLEAR CACHE 명령을 실행하십시오. + # 각 zone_id를 반복하고 캐시 지우기 명령을 실행합니다. for ZONE_ID in "${ZONE_IDS[@]}"; do - echo "Zone_ID의 캐시 지우기 :$ZONE_ID" + echo "zone_id에 대한 캐시 지우기:$ZONE_ID" curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \ -H "X-Auth-Email: $EMAIL" \ -H "X-Auth-Key: $API_TOKEN" \ @@ -1685,16 +1780,15 @@ cf_purge_cache() { --data '{"purge_everything":true}' done - echo "캐시 클리어 요청이 전송되었습니다." + echo "캐시 삭제 요청이 전송되었습니다." } web_cache() { - send_stats "사이트 캐시를 정리하십시오" + send_stats "사이트 캐시 지우기" cf_purge_cache cd /home/web && docker compose restart - restart_redis } @@ -1704,25 +1798,25 @@ web_del() { send_stats "사이트 데이터 삭제" yuming_list="${1:-}" if [ -z "$yuming_list" ]; then - read -e -p "사이트 데이터를 삭제하려면 도메인 이름을 입력하십시오 (여러 도메인 이름이 공간별로 분리됩니다)." yuming_list + read -e -p "사이트 데이터를 삭제하려면 도메인 이름을 입력하세요(여러 도메인 이름은 공백으로 구분)." yuming_list if [[ -z "$yuming_list" ]]; then return fi fi for yuming in $yuming_list; do - echo "도메인 이름 삭제 :$yuming" + echo "도메인 이름을 삭제하는 중입니다:$yuming" rm -r /home/web/html/$yuming > /dev/null 2>&1 rm /home/web/conf.d/$yuming.conf > /dev/null 2>&1 rm /home/web/certs/${yuming}_key.pem > /dev/null 2>&1 rm /home/web/certs/${yuming}_cert.pem > /dev/null 2>&1 - # 도메인 이름을 데이터베이스 이름으로 변환합니다 + # 도메인 이름을 데이터베이스 이름으로 변환 dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') - # 오류를 피하기 위해 삭제하기 전에 데이터베이스가 존재하는지 확인하십시오. - echo "데이터베이스 삭제 :$dbname" + # 오류를 방지하려면 데이터베이스를 삭제하기 전에 데이터베이스가 존재하는지 확인하세요. + echo "데이터베이스 삭제 중:$dbname" docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE ${dbname};" > /dev/null 2>&1 done @@ -1738,23 +1832,23 @@ nginx_waf() { wget -O /home/web/nginx.conf "${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf" fi - # 모드 매개 변수에 따라 WAF를 켜거나 끄기로 결정 + # 모드 매개변수에 따라 WAF를 켤지 끌지 결정합니다. if [ "$mode" == "on" ]; then - # WAF 켜기 : 주석을 제거하십시오 + # WAF 켜기: 댓글 제거 sed -i 's|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity on;|\1modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 elif [ "$mode" == "off" ]; then - # waf 닫기 : 댓글을 추가하십시오 + # WAF 끄기: 댓글 추가 sed -i 's|^load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|# load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity on;|\1# modsecurity on;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^\(\s*\)modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|\1# modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "유효하지 않은 매개 변수 : 'ON'또는 'OFF'사용" + echo "잘못된 인수: 'on' 또는 'off'를 사용하세요." return 1 fi - # Nginx 이미지를 확인하고 상황에 따라 처리하십시오. + # nginx 이미지를 확인하고 그에 따라 처리하십시오. if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1768,7 +1862,7 @@ check_waf_status() { if grep -q "^\s*#\s*modsecurity on;" /home/web/nginx.conf; then waf_status="" elif grep -q "modsecurity on;" /home/web/nginx.conf; then - waf_status=" WAF已开启" + waf_status="WAF가 켜져 있습니다." else waf_status="" fi @@ -1776,8 +1870,8 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then - CFmessage=" cf模式已开启" + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then + CFmessage="cf 모드가 켜져 있습니다" else CFmessage="" fi @@ -1801,11 +1895,11 @@ patch_wp_memory_limit() { local TARGET_DIR="/home/web/html" # 路径写死 find "$TARGET_DIR" -type f -name "wp-config.php" | while read -r FILE; do - # 오래된 정의를 삭제하십시오 + # 이전 정의 삭제 sed -i "/define(['\"]WP_MEMORY_LIMIT['\"].*/d" "$FILE" sed -i "/define(['\"]WP_MAX_MEMORY_LIMIT['\"].*/d" "$FILE" - # "Happy Publishing"과 함께 새로운 정의를 삽입하십시오. + # "HappyPublishing"이 포함된 줄 앞에 새 정의를 삽입합니다. awk -v insert="define('WP_MEMORY_LIMIT', '$MEMORY_LIMIT');\ndefine('WP_MAX_MEMORY_LIMIT', '$MAX_MEMORY_LIMIT');" \ ' /Happy publishing/ { @@ -1828,12 +1922,12 @@ patch_wp_debug() { local TARGET_DIR="/home/web/html" # 路径写死 find "$TARGET_DIR" -type f -name "wp-config.php" | while read -r FILE; do - # 오래된 정의를 삭제하십시오 + # 이전 정의 삭제 sed -i "/define(['\"]WP_DEBUG['\"].*/d" "$FILE" sed -i "/define(['\"]WP_DEBUG_DISPLAY['\"].*/d" "$FILE" sed -i "/define(['\"]WP_DEBUG_LOG['\"].*/d" "$FILE" - # "Happy Publishing"과 함께 새로운 정의를 삽입하십시오. + # "HappyPublishing"이 포함된 줄 앞에 새 정의를 삽입합니다. awk -v insert="define('WP_DEBUG_DISPLAY', $DEBUG_DISPLAY);\ndefine('WP_DEBUG_LOG', $DEBUG_LOG);" \ ' /Happy publishing/ { @@ -1847,6 +1941,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # 이전 정의 삭제 + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # 삽입 콘텐츠 생성 + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # '행복한 출판' 앞에 삽입 + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1856,7 +1987,7 @@ nginx_br() { fi if [ "$mode" == "on" ]; then - # Brotli를 켜십시오 : 주석을 제거하십시오 + # Brotli 켜기: 댓글 제거 sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1870,7 +2001,7 @@ nginx_br() { sed -i '/brotli_types/,+6 s/^\(\s*\)#\s*/\1/' /home/web/nginx.conf elif [ "$mode" == "off" ]; then - # Brotli를 닫습니다 : 주석을 추가하십시오 + # Brotli 닫기: 댓글 추가 sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|# load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1886,11 +2017,11 @@ nginx_br() { }' /home/web/nginx.conf else - echo "유효하지 않은 매개 변수 : 'ON'또는 'OFF'사용" + echo "잘못된 인수: 'on' 또는 'off'를 사용하세요." return 1 fi - # Nginx 이미지를 확인하고 상황에 따라 처리하십시오. + # nginx 이미지를 확인하고 그에 따라 처리하십시오. if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1912,7 +2043,7 @@ nginx_zstd() { fi if [ "$mode" == "on" ]; then - # ZSTD를 켜십시오 : 주석을 제거하십시오 + # Zstd 켜기: 주석 제거 sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1927,7 +2058,7 @@ nginx_zstd() { elif [ "$mode" == "off" ]; then - # Zstd를 닫습니다 : 주석을 추가하십시오 + # Zstd 닫기: 설명 추가 sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_filter_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 sed -i 's|^load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|# load_module /etc/nginx/modules/ngx_http_zstd_static_module.so;|' /home/web/nginx.conf > /dev/null 2>&1 @@ -1943,11 +2074,11 @@ nginx_zstd() { else - echo "유효하지 않은 매개 변수 : 'ON'또는 'OFF'사용" + echo "잘못된 인수: 'on' 또는 'off'를 사용하세요." return 1 fi - # Nginx 이미지를 확인하고 상황에 따라 처리하십시오. + # nginx 이미지를 확인하고 그에 따라 처리하십시오. if grep -q "kjlion/nginx:alpine" /home/web/docker-compose.yml; then docker exec nginx nginx -s reload else @@ -1974,7 +2105,7 @@ nginx_gzip() { elif [ "$mode" == "off" ]; then sed -i 's|^\(\s*\)gzip on;|\1# gzip on;|' /home/web/nginx.conf > /dev/null 2>&1 else - echo "유효하지 않은 매개 변수 : 'ON'또는 'OFF'사용" + echo "잘못된 인수: 'on' 또는 'off'를 사용하세요." return 1 fi @@ -1990,45 +2121,42 @@ nginx_gzip() { web_security() { send_stats "LDNMP 환경 방어" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "서버 웹 사이트 방어 프로그램${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "서버 웹사이트 방어 프로그램${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" - echo "1. 방어 프로그램을 설치하십시오" + echo "1. 방어 프로그램 설치" echo "------------------------" - echo "5. SSH 차단 레코드보기 6. 웹 사이트 차단 레코드보기" - echo "7. 방어 규칙 목록보기 8. 로그의 실시간 모니터링보기" + echo "5. SSH 차단 기록 보기 6. 웹사이트 차단 기록 보기" + echo "7. 방어규칙 목록 보기 8. 실시간 모니터링을 위한 로그 보기" echo "------------------------" - echo "11. 인터셉트 매개 변수 구성 12. 차단 된 모든 IP를 지우십시오" + echo "11. 차단 매개변수 구성 12. 차단된 IP 모두 삭제" echo "------------------------" - echo "21. CloudFlare 모드 22. 5 초 방패의 높은 하중" + echo "21. cloudflare 모드 22. 고부하에서 5초 보호 활성화" echo "------------------------" - echo "31. WAF 32를 켜십시오. WAF를 끄십시오" + echo "31. WAF 켜기 32. WAF 끄기" echo "33. DDOS 방어 켜기 34. DDOS 방어 끄기" echo "------------------------" - echo "9. 방어 프로그램을 제거하십시오" + echo "9. 방어 프로그램 제거" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,93 +2170,94 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null - echo "Fail2ban 방어 프로그램은 제거되었습니다" + echo "Fail2Ban 방어 프로그램이 제거되었습니다." + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) - send_stats "CloudFlare 모드" - echo "CF 배경의 오른쪽 상단 모서리로 이동하여 왼쪽의 API 토큰을 선택하고 글로벌 API 키를 얻습니다." + send_stats "클라우드플레어 모드" + echo "cf 백엔드 오른쪽 상단에 있는 내 프로필로 이동하여 왼쪽에 있는 API 토큰을 선택하고 글로벌 API 키를 받으세요." echo "https://dash.cloudflare.com/login" - read -e -p "CF 계정 번호를 입력하십시오." cfuser - read -e -p "CF의 글로벌 API 키를 입력하십시오." cftoken + read -e -p "CF의 계좌번호를 입력하세요:" cfuser + read -e -p "CF의 글로벌 API 키를 입력하세요:" cftoken wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status - echo "CloudFlare 모드는 CF 배경, Site-Security-Events에서 인터셉트 레코드를 보도록 구성됩니다." + echo "Cloudflare 모드가 구성되었으며, 차단 기록은 cf 백그라운드, site-security-events에서 볼 수 있습니다." ;; 22) - send_stats "5 초 방패의 높은 하중" - echo -e "${gl_huang}웹 사이트는 5 분마다 자동으로 감지됩니다. 높은 부하가 감지되면 방패가 자동으로 켜지고 5 초 동안 낮은 부하가 자동으로 꺼집니다.${gl_bai}" + send_stats "고부하로 5초 쉴드 가능" + echo -e "${gl_huang}웹사이트는 5분마다 자동으로 감지합니다. 고부하를 감지하면 자동으로 실드를 열고, 저부하를 감지하면 자동으로 5초 동안 실드를 닫습니다.${gl_bai}" echo "--------------" - echo "CF 매개 변수 가져 오기 :" - echo -e "CF 배경의 오른쪽 상단 모서리로 이동하여 왼쪽의 API 토큰을 선택하고 얻습니다.${gl_huang}Global API Key${gl_bai}" - echo -e "CF 배경 도메인 이름 요약 페이지의 오른쪽 하단으로 이동하려면${gl_huang}지역 ID${gl_bai}" + echo "CF 매개변수 가져오기:" + echo -e "cf 백엔드 오른쪽 상단에 있는 내 프로필로 이동하여 왼쪽에 있는 API 토큰을 선택하고${gl_huang}Global API Key${gl_bai}" + echo -e "cf 백엔드 도메인 이름 요약 페이지 오른쪽 하단으로 이동하여 가져오세요.${gl_huang}지역 ID${gl_bai}" echo "https://dash.cloudflare.com/login" echo "--------------" - read -e -p "CF 계정 번호를 입력하십시오." cfuser - read -e -p "CF의 글로벌 API 키를 입력하십시오." cftoken - read -e -p "CF에 도메인 이름의 영역 ID를 입력하십시오." cfzonID + read -e -p "CF의 계좌번호를 입력하세요:" cfuser + read -e -p "CF의 글로벌 API 키를 입력하세요:" cftoken + read -e -p "CF에 도메인 이름의 영역 ID를 입력하세요." cfzonID cd ~ install jq bc @@ -2145,23 +2274,23 @@ web_security() { if [ -z "$existing_cron" ]; then (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "고 부하 자동 방패 오프닝 스크립트가 추가되었습니다" + echo "고부하 자동 쉴드 오픈 스크립트가 추가되었습니다." else - echo "자동 방패 스크립트가 이미 존재합니다. 추가 할 필요가 없습니다." + echo "자동 방패 열기 스크립트가 이미 있으므로 추가할 필요가 없습니다." fi ;; 31) nginx_waf on - echo "사이트 waf가 활성화되어 있습니다" - send_stats "사이트 waf가 활성화되어 있습니다" + echo "사이트 WAF가 활성화되었습니다" + send_stats "사이트 WAF가 활성화되었습니다" ;; 32) nginx_waf off - echo "사이트 waf가 닫혔습니다" - send_stats "사이트 waf가 닫혔습니다" + echo "사이트 WAF가 다운되었습니다" + send_stats "사이트 WAF가 다운되었습니다" ;; 33) @@ -2176,26 +2305,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { - -CONFIG_FILE="/home/web/nginx.conf" +check_ldnmp_mode() { -# 현재 Worker_Processes 설정 값을 얻으십시오 -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# 값에 따라 모드 정보를 설정합니다 -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # MySQL 구성 파일에 4096M이 포함되어 있는지 확인하세요. + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info="고성능 모드" + else + mode_info="표준 모드" + fi @@ -2204,25 +2330,25 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" - # ZSTD가 활성화되어 있고 주석이 없는지 확인하십시오 (전체 라인은 ZSTD 켜기로 시작합니다.) + # zstd가 켜져 있고 주석 처리가 해제되어 있는지 확인하세요. (전체 줄은 zstd on으로 시작됩니다.) if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then - zstd_status=" zstd压缩已开启" + zstd_status="zstd 압축이 켜져 있습니다" else zstd_status="" fi - # Brotli가 활성화되어 있고 댓글이 없는지 확인하십시오 + # brotli가 활성화되어 있고 주석 처리가 해제되어 있는지 확인하세요. if grep -qE '^\s*brotli\s+on;' "$CONFIG_FILE"; then - br_status=" br压缩已开启" + br_status="br압축이 켜져 있습니다" else br_status="" fi - # GZIP가 활성화되어 있고 댓글을 달지 않은지 확인하십시오 + # gzip이 활성화되어 있고 주석 처리가 해제되어 있는지 확인하세요. if grep -qE '^\s*gzip\s+on;' "$CONFIG_FILE"; then - gzip_status=" gzip压缩已开启" + gzip_status="gzip 압축이 켜져 있습니다" else gzip_status="" fi @@ -2233,28 +2359,30 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear - send_stats "LDNMP 환경을 최적화하십시오" - echo -e "LDNMP 환경을 최적화하십시오${gl_lv}${mode_info}${gzip_status}${br_status}${zstd_status}${gl_bai}" + send_stats "LDNMP 환경 최적화" + echo -e "LDNMP 환경 최적화${gl_lv}${mode_info}${gzip_status}${br_status}${zstd_status}${gl_bai}" echo "------------------------" - echo "1. 표준 모드 2. 고성능 모드 (2H4G 이상 권장)" + echo "1. 표준 모드 2. 고성능 모드(2H4G 이상 권장)" echo "------------------------" - echo "3. GZIP 압축 켜기 4. GZIP 압축 끄기" - echo "5. BR 압축 켜기 6. BR 압축 끄기" - echo "7. ZSTD 압축 켜기 8. ZSTD 압축 끄기" + echo "3. gzip 압축 켜기 4. gzip 압축 끄기" + echo "5. br 압축을 켭니다. 6. br 압축을 끕니다." + echo "7. zstd 압축을 켭니다. 8. zstd 압축을 끕니다." echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) send_stats "사이트 표준 모드" - # nginx 튜닝 - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf + # PHP 튜닝 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2282,19 +2410,20 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced - echo "LDNMP 환경은 표준 모드로 설정되었습니다" + echo "LDNMP 환경이 표준 모드로 설정되었습니다." ;; 2) send_stats "사이트 고성능 모드" # nginx 튜닝 - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf # PHP 튜닝 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2321,10 +2450,9 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_web_server - echo "LDNMP 환경은 고성능 모드로 설정되었습니다" + echo "LDNMP 환경이 고성능 모드로 설정되었습니다." ;; 3) @@ -2371,23 +2499,30 @@ web_optimization() { +check_docker_app() { + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then + check_docker="${gl_lv}설치됨${gl_bai}" + else + check_docker="${gl_hui}설치되지 않음${gl_bai}" + fi +} -check_docker_app() { +# check_docker_app() { -if docker inspect "$docker_name" &>/dev/null; then - check_docker="${gl_lv}已安装${gl_bai}" -else - check_docker="${gl_hui}未安装${gl_bai}" -fi +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then +# check_docker="${gl_lv}가 ${gl_bai}를 설치했습니다." +# else +# check_docker="${gl_hui}이(가) ${gl_bai}" 설치되지 않았습니다. +# fi -} +# } check_docker_app_ip() { echo "------------------------" -echo "액세스 주소 :" +echo "방문 주소:" ip_address @@ -2416,59 +2551,66 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. 지역점검 + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # 컨테이너 생성 시간과 이미지 이름을 얻으십시오 + # 2. 로컬 미러 정보 얻기 local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) - - # 거울 창고 및 태그 추출 - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} + [[ -z "$container_info" ]] && return - # 기본 레이블이 최신입니다 - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" - - # 공식 이미지에 대한 지원을 추가하십시오 - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. 지능형 라우팅 판단 + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- 시나리오 A: GitHub(ghcr.io)의 미러링 --- + # 웨어하우스 경로를 추출합니다(예: ghcr.io/onexru/oneimg -> onexru/oneimg). + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # 참고: ghcr.io의 API는 비교적 복잡합니다. 일반적으로 가장 빠른 방법은 GitHub Repo 릴리스를 확인하는 것입니다. + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- 시나리오 B: 특별 지정(Docker Hub에서도 GitHub 릴리스로 판단하고 싶습니다) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # Docker Hub API에서 이미지 게시 시간을 얻으십시오 - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- 시나리오 C: 표준 Docker 허브 --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # 획득 시간을 확인하십시오 - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # 타임 스탬프를 비교하십시오 - if [[ $container_created_ts -lt $last_updated_ts ]]; then - update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" + # 4. 타임스탬프 비교 + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then + update_status="${gl_huang}새 버전이 발견되었습니다!${gl_bai}" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 - # 컨테이너의 IP 주소를 가져옵니다 + # 컨테이너의 IP 주소 가져오기 local container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name_or_id") if [ -z "$container_ip" ]; then @@ -2478,34 +2620,34 @@ block_container_port() { install iptables - # 다른 모든 IP를 점검하고 차단하십시오 + # 다른 모든 IP를 확인하고 차단하세요. if ! iptables -C DOCKER-USER -p tcp -d "$container_ip" -j DROP &>/dev/null; then iptables -I DOCKER-USER -p tcp -d "$container_ip" -j DROP fi - # 지정된 IP를 확인하고 해제하십시오 + # 지정된 IP 확인 및 해제 if ! iptables -C DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # 로컬 네트워크 127.0.0.0/8을 확인하고 해제하십시오 + # 로컬 네트워크 127.0.0.0/8 확인 및 허용 if ! iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi - # 다른 모든 IP를 점검하고 차단하십시오 + # 다른 모든 IP를 확인하고 차단하세요. if ! iptables -C DOCKER-USER -p udp -d "$container_ip" -j DROP &>/dev/null; then iptables -I DOCKER-USER -p udp -d "$container_ip" -j DROP fi - # 지정된 IP를 확인하고 해제하십시오 + # 지정된 IP 확인 및 해제 if ! iptables -C DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # 로컬 네트워크 127.0.0.0/8을 확인하고 해제하십시오 + # 로컬 네트워크 127.0.0.0/8 확인 및 허용 if ! iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -I DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2515,7 +2657,7 @@ block_container_port() { fi - echo "IP+ 포트는 서비스에 액세스하는 것이 차단되었습니다" + echo "IP+포트가 서비스 접근을 차단했습니다." save_iptables_rules } @@ -2526,7 +2668,7 @@ clear_container_rules() { local container_name_or_id=$1 local allowed_ip=$2 - # 컨테이너의 IP 주소를 가져옵니다 + # 컨테이너의 IP 주소 가져오기 local container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$container_name_or_id") if [ -z "$container_ip" ]; then @@ -2541,12 +2683,12 @@ clear_container_rules() { iptables -D DOCKER-USER -p tcp -d "$container_ip" -j DROP fi - # 지정된 IP를 공개하기위한 규칙을 지우십시오 + # 특정 IP를 허용하는 규칙 지우기 if iptables -C DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # 로컬 네트워크 릴리스 규칙을 지우십시오. 127.0.0.0/8 + # 로컬 네트워크 127.0.0.0/8을 허용하는 규칙을 지웁니다. if iptables -C DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p tcp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2560,12 +2702,12 @@ clear_container_rules() { iptables -D DOCKER-USER -p udp -d "$container_ip" -j DROP fi - # 지정된 IP를 공개하기위한 규칙을 지우십시오 + # 특정 IP를 허용하는 규칙 지우기 if iptables -C DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s "$allowed_ip" -d "$container_ip" -j ACCEPT fi - # 로컬 네트워크 릴리스 규칙을 지우십시오. 127.0.0.0/8 + # 로컬 네트워크 127.0.0.0/8을 허용하는 규칙을 지웁니다. if iptables -C DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT &>/dev/null; then iptables -D DOCKER-USER -p udp -s 127.0.0.0/8 -d "$container_ip" -j ACCEPT fi @@ -2576,7 +2718,7 @@ clear_container_rules() { fi - echo "IP+포트는 서비스에 액세스 할 수있었습니다" + echo "IP+포트로 서비스 접속이 허용되었습니다" save_iptables_rules } @@ -2590,25 +2732,25 @@ block_host_port() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "오류 : 액세스 할 수있는 포트 번호와 IP를 제공하십시오." - echo "사용법 : block_host_port <포트 번호> <승인 된 ip>" + echo "오류: 액세스를 허용하려면 포트 번호와 IP를 입력하세요." + echo "사용법: block_host_port <포트 번호> <허용 IP>" return 1 fi install iptables - # 다른 모든 IP 액세스를 거부했습니다 + # 다른 모든 IP의 접근을 거부 if ! iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -j DROP fi - # 지정된 IP 액세스를 허용합니다 + # 지정된 IP에 대한 접근을 허용 if ! iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # 로컬 액세스를 허용합니다 + # 로컬 액세스 허용 if ! iptables -C INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -I INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi @@ -2617,27 +2759,27 @@ block_host_port() { - # 다른 모든 IP 액세스를 거부했습니다 + # 다른 모든 IP의 접근을 거부 if ! iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -j DROP fi - # 지정된 IP 액세스를 허용합니다 + # 지정된 IP에 대한 접근을 허용 if ! iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # 로컬 액세스를 허용합니다 + # 로컬 액세스 허용 if ! iptables -C INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -I INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 확립 및 관련 연결을 위해 트래픽을 허용합니다 + # 확립된 관련 연결에 대한 트래픽 허용 if ! iptables -C INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT &>/dev/null; then iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT fi - echo "IP+ 포트는 서비스에 액세스하는 것이 차단되었습니다" + echo "IP+포트가 서비스 접근을 차단했습니다." save_iptables_rules } @@ -2649,47 +2791,47 @@ clear_host_port_rules() { local allowed_ip=$2 if [[ -z "$port" || -z "$allowed_ip" ]]; then - echo "오류 : 액세스 할 수있는 포트 번호와 IP를 제공하십시오." - echo "사용법 : CLEAR_HOST_PORT_RULES <포트 번호> <승인 IP>" + echo "오류: 액세스를 허용하려면 포트 번호와 IP를 입력하세요." + echo "사용법:clear_host_port_rules <포트 번호> <허용 IP>" return 1 fi install iptables - # 다른 모든 IP 액세스를 차단하는 명확한 규칙 + # 다른 모든 IP의 접근을 차단하는 규칙을 해제하세요. if iptables -C INPUT -p tcp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -j DROP fi - # 기본 액세스를 허용하는 명확한 규칙 + # 로컬 액세스를 허용하는 명확한 규칙 if iptables -C INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 지정된 IP 액세스를 허용하는 명확한 규칙 + # 지정된 IP로부터의 액세스를 허용하는 명확한 규칙 if iptables -C INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p tcp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - # 다른 모든 IP 액세스를 차단하는 명확한 규칙 + # 다른 모든 IP의 접근을 차단하는 규칙을 해제하세요. if iptables -C INPUT -p udp --dport "$port" -j DROP &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -j DROP fi - # 기본 액세스를 허용하는 명확한 규칙 + # 로컬 액세스를 허용하는 명확한 규칙 if iptables -C INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s 127.0.0.0/8 -j ACCEPT fi - # 지정된 IP 액세스를 허용하는 명확한 규칙 + # 지정된 IP로부터의 액세스를 허용하는 명확한 규칙 if iptables -C INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT &>/dev/null; then iptables -D INPUT -p udp --dport "$port" -s "$allowed_ip" -j ACCEPT fi - echo "IP+포트는 서비스에 액세스 할 수있었습니다" + echo "IP+포트로 서비스 접속이 허용되었습니다" save_iptables_rules } @@ -2698,16 +2840,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2720,7 +2879,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2734,26 +2893,28 @@ while true; do echo "1. 설치 2. 업데이트 3. 제거" echo "------------------------" echo "5. 도메인 이름 액세스 추가 6. 도메인 이름 액세스 삭제" - echo "7. IP+ 포트 액세스 허용 8. 블록 IP+ 포트 액세스" + echo "7. IP+포트 접근 허용 8. IP+포트 접근 차단" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) - check_disk_space $app_size - read -e -p "응용 프로그램 외부 서비스 포트를 입력하고 기본값을 입력하십시오.${docker_port}포트:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "애플리케이션 외부 서비스 포트를 입력하고 Enter를 누르면 기본적으로 사용됩니다.${docker_port}포트:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + add_app_id + clear - echo "$docker_name설치" + echo "$docker_name설치 완료" check_docker_app_ip echo "" $docker_use @@ -2764,8 +2925,11 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum + + add_app_id + clear - echo "$docker_name설치" + echo "$docker_name설치 완료" check_docker_app_ip echo "" $docker_use @@ -2777,20 +2941,22 @@ while true; do docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf - echo "앱이 제거되었습니다" - send_stats "제거하십시오$docker_name" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "앱이 제거되었습니다." + send_stats "제거$docker_name" ;; 5) - echo "${docker_name}도메인 액세스 설정" - send_stats "${docker_name}도메인 액세스 설정" + echo "${docker_name}도메인 이름 액세스 설정" + send_stats "${docker_name}도메인 이름 액세스 설정" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" ;; 6) - echo "도메인 이름 형식 example.com은 https : //와 함께 제공되지 않습니다." + echo "https://가 없는 도메인 이름 형식 example.com" web_del ;; @@ -2800,7 +2966,7 @@ while true; do ;; 8) - send_stats "IP 액세스를 차단하십시오${docker_name}" + send_stats "IP 접근 차단${docker_name}" block_container_port "$docker_name" "$ipv4_address" ;; @@ -2817,7 +2983,6 @@ done - docker_app_plus() { send_stats "$app_name" while true; do @@ -2827,7 +2992,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2841,39 +3006,51 @@ docker_app_plus() { echo "1. 설치 2. 업데이트 3. 제거" echo "------------------------" echo "5. 도메인 이름 액세스 추가 6. 도메인 이름 액세스 삭제" - echo "7. IP+ 포트 액세스 허용 8. 블록 IP+ 포트 액세스" + echo "7. IP+포트 접근 허용 8. IP+포트 접근 차단" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) - check_disk_space $app_size - read -e -p "응용 프로그램 외부 서비스 포트를 입력하고 기본값을 입력하십시오.${docker_port}포트:" app_port + setup_docker_dir + check_disk_space $app_size /home/docker + read -e -p "애플리케이션 외부 서비스 포트를 입력하고 Enter를 누르면 기본적으로 사용됩니다.${docker_port}포트:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + + add_app_id + send_stats "$app_name설치하다" ;; + 2) docker_app_update + add_app_id + send_stats "$app_name고쳐 쓰다" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_name제거" ;; + 5) - echo "${docker_name}도메인 액세스 설정" - send_stats "${docker_name}도메인 액세스 설정" + echo "${docker_name}도메인 이름 액세스 설정" + send_stats "${docker_name}도메인 이름 액세스 설정" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) - echo "도메인 이름 형식 example.com은 https : //와 함께 제공되지 않습니다." + echo "https://가 없는 도메인 이름 형식 example.com" web_del ;; 7) @@ -2881,7 +3058,7 @@ docker_app_plus() { clear_container_rules "$docker_name" "$ipv4_address" ;; 8) - send_stats "IP 액세스를 차단하십시오${docker_name}" + send_stats "IP 접근 차단${docker_name}" block_container_port "$docker_name" "$ipv4_address" ;; *) @@ -2920,7 +3097,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2929,7 +3106,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2939,7 +3116,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -2966,17 +3143,17 @@ tmux_run_d() { local base_name="tmuxd" local tmuxd_ID=1 -# 세션이 존재하는지 확인하는 기능 +# 세션이 존재하는지 확인하는 함수 session_exists() { tmux has-session -t $1 2>/dev/null } -# 존재하지 않는 세션 이름이 발견 될 때까지 루프 +# 존재하지 않는 세션 이름을 찾을 때까지 반복 while session_exists "$base_name-$tmuxd_ID"; do local tmuxd_ID=$((tmuxd_ID + 1)) done -# 새로운 TMUX 세션을 만듭니다 +# 새 tmux 세션 만들기 tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" @@ -2985,52 +3162,41 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx +} + +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}설치됨${gl_bai}" + else + check_f2b_status="${gl_hui}설치되지 않음${gl_bai}" + fi } f2b_install_sshd() { - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf - else + fi + + if command -v apt &>/dev/null; then install rsyslog systemctl start rsyslog systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog fi - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } f2b_sshd() { @@ -3051,7 +3217,7 @@ server_reboot() { read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}现在重启服务器吗?(Y/N): ")" rboot case "$rboot" in [Yy]) - echo "다시 시작" + echo "다시 시작됨" reboot ;; *) @@ -3099,7 +3265,7 @@ ldnmp_install_status_one() { if docker inspect "php" &>/dev/null; then clear send_stats "LDNMP 환경을 다시 설치할 수 없습니다" - echo -e "${gl_huang}힌트:${gl_bai}웹 사이트 구성 환경이 설치되었습니다. 다시 설치할 필요가 없습니다!" + echo -e "${gl_huang}힌트:${gl_bai}홈페이지 구축 환경이 설치되었습니다. 다시 설치할 필요가 없습니다!" break_end linux_ldnmp fi @@ -3109,12 +3275,11 @@ ldnmp_install_status_one() { ldnmp_install_all() { cd ~ -send_stats "LDNMP 환경을 설치하십시오" +send_stats "LDNMP 환경 설치" root_use clear -echo -e "${gl_huang}LDNMP 환경이 설치되지 않았으며 LDNMP 환경 설치를 시작하십시오 ...${gl_bai}" -check_disk_space 3 -check_port +echo -e "${gl_huang}LDNMP 환경이 설치되지 않았습니다. LDNMP 환경 설치를 시작합니다...${gl_bai}" +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3126,12 +3291,11 @@ install_ldnmp nginx_install_all() { cd ~ -send_stats "Nginx 환경을 설치하십시오" +send_stats "nginx 환경 설치" root_use clear -echo -e "${gl_huang}Nginx가 설치되지 않았고 Nginx 환경 설치 시작 ...${gl_bai}" -check_disk_space 1 -check_port +echo -e "${gl_huang}nginx가 설치되지 않았습니다. nginx 환경 설치를 시작하세요...${gl_bai}" +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3140,8 +3304,8 @@ nginx_upgrade clear local nginx_version=$(docker exec nginx nginx -v 2>&1) local nginx_version=$(echo "$nginx_version" | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+") -echo "Nginx가 설치되었습니다" -echo -e "현재 버전 :${gl_huang}v$nginx_version${gl_bai}" +echo "nginx가 설치되었습니다" +echo -e "현재 버전:${gl_huang}v$nginx_version${gl_bai}" echo "" } @@ -3152,7 +3316,7 @@ echo "" ldnmp_install_status() { if ! docker inspect "php" &>/dev/null; then - send_stats "먼저 LDNMP 환경을 설치하십시오" + send_stats "먼저 LDNMP 환경을 설치해 주세요" ldnmp_install_all fi @@ -3162,7 +3326,7 @@ ldnmp_install_status() { nginx_install_status() { if ! docker inspect "nginx" &>/dev/null; then - send_stats "Nginx 환경을 먼저 설치하십시오" + send_stats "먼저 nginx 환경을 설치해주세요" nginx_install_all fi @@ -3173,18 +3337,29 @@ nginx_install_status() { ldnmp_web_on() { clear - echo "당신 것$webname세워짐!" + echo "당신의$webname건설되었습니다!" echo "https://$yuming" echo "------------------------" - echo "$webname설치 정보는 다음과 같습니다." + echo "$webname설치정보는 다음과 같습니다." } nginx_web_on() { - clear - echo "당신 것$webname세워짐!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + echo "당신의$webname건설되었습니다!" + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3195,73 +3370,93 @@ ldnmp_wp() { webname="WordPress" yuming="${1:-}" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" if [ -z "$yuming" ]; then add_yuming fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# Echo "데이터베이스 이름 : $ dbname" -# Echo "사용자 이름 : $ dbuse" -# echo "비밀번호 : $ dbusepasswd" -# Echo "데이터베이스 주소 : mysql" -# 에코 "테이블 접두사 : wp_" } + ldnmp_Proxy() { clear - webname="反向代理-IP+端口" + webname="역방향 프록시-IP+포트" yuming="${1:-}" reverseproxy="${2:-}" port="${3:-}" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "반세대 IP를 입력하십시오 :" reverseproxy + read -e -p "세대 방지 IP를 입력하십시오(기본값은 로컬 IP 127.0.0.1로 설정하려면 Enter를 누르십시오)." reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then - read -e -p "반세대 포트를 입력하십시오 :" port + read -e -p "안티 세대 포트를 입력하십시오:" port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 동적으로 추가/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3271,41 +3466,43 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear - webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" + webname="역방향 프록시-로드 밸런싱" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" if [ -z "$yuming" ]; then add_yuming fi - # 사용자가 입력 한 여러 IP를 얻습니다 : 포트 (공간별로 분리) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then - read -e -p "공간으로 분리 된 여러 반세대 IP+ 포트를 입력하십시오 (예 : 127.0.0.1:3000 127.0.1:3002) :" reverseproxy_port + read -e -p "여러 개의 세대 방지 IP+포트를 공백으로 구분하여 입력하세요(예: 127.0.0.1:3000 127.0.0.1:3002)." reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # 상류 구성을 동적으로 생성합니다 upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # 템플릿의 자리 표시자를 교체하십시오 - sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i "s/# 동적으로 추가/$upstream_servers/g" /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" nginx_http_on docker exec nginx nginx -s reload @@ -3314,6 +3511,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "서비스 이름" "통신 유형" "현지 주소" "백엔드 주소" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # 서비스 이름은 파일 이름을 사용합니다. + service_name=$(basename "$conf" .conf) + + # 업스트림 블록에서 서버 백엔드 IP:포트 가져오기 + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # 청취 포트 가져오기 + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # 기본 로컬 IP + ip_address + local_ip="$ipv4_address" + + # 먼저 파일 이름 접미사 또는 내용으로 판단하여 통신 유형을 가져옵니다. + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # 스플라이스 청취 IP:포트 + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "4계층 프록시 스트리밍" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "스트림 4계층 프록시 전달 도구$check_docker $update_status" + echo "NGINX 스트림은 고성능 전송 계층 트래픽 전달 및 로드 밸런싱을 달성하는 데 사용되는 NGINX의 TCP/UDP 프록시 모듈입니다." + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. 설치 2. 업데이트 3. 제거" + echo "------------------------" + echo "4. 포워딩 서비스 추가 5. 포워딩 서비스 수정 6. 포워딩 서비스 삭제" + echo "------------------------" + echo "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택 항목을 입력하세요." choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "Stream 4계층 에이전트 설치" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "Stream 4계층 프록시 업데이트" + ;; + 3) + read -e -p "nginx 컨테이너를 삭제하시겠습니까? 이는 웹사이트 기능에 영향을 미칠 수 있습니다! (예/아니요):" confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "Stream 4계층 프록시 업데이트" + echo "nginx 컨테이너가 삭제되었습니다." + else + echo "작업이 취소되었습니다." + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "레이어 4 프록시 추가" + ;; + 5) + send_stats "전달 구성 수정" + read -e -p "편집하려는 서비스 이름을 입력하십시오:" stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "레이어 4 프록시 수정" + ;; + 6) + send_stats "전달 구성 삭제" + read -e -p "삭제하려는 서비스 이름을 입력하세요." stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "레이어 4 프록시 삭제" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="스트리밍 4계층 프록시-로드 밸런싱" + + send_stats "설치하다$webname" + echo "배포 시작$webname" + + # 에이전트 이름 가져오기 + read -rp "프록시 전달 이름(예: mysql_proxy)을 입력하세요." proxy_name + if [ -z "$proxy_name" ]; then + echo "이름은 비워둘 수 없습니다."; return 1 + fi + + # 수신 포트 가져오기 + read -rp "로컬 수신 포트(예: 3306)를 입력하십시오." listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "포트는 숫자여야 합니다."; return 1 + fi + + echo "계약 유형을 선택하십시오:" + echo "1. TCP 2. UDP" + read -rp "일련 번호 [1-2]를 입력하십시오:" proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "잘못된 선택"; return 1 ;; + esac + + read -e -p "하나 이상의 백엔드 IP+포트를 공백으로 구분하여 입력하세요(예: 10.13.0.2:3306 10.13.0.3:3306)." reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 동적으로 추가/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "당신의$webname건설되었습니다!" + echo "------------------------" + echo "방문 주소:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3331,11 +3722,11 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear send_stats "LDNMP 사이트 관리" @@ -3343,8 +3734,7 @@ ldnmp_web_status() { echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output}인증서 만료 시간" + echo -e "대지:${output}인증서 만료 시간" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3355,9 +3745,28 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "데이터 베이스:${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" @@ -3371,46 +3780,42 @@ ldnmp_web_status() { echo "" echo "작동하다" echo "------------------------" - echo "1. 도메인 이름 인증서 신청/업데이트 2. 사이트 도메인 이름 변경" - echo "3. 사이트 캐시 정리 4. 관련 사이트 만들기" - echo "5. 액세스 로그보기 6. 오류 로그보기" - echo "7. 글로벌 구성 편집 8. 사이트 구성 편집" - echo "9. 사이트 데이터베이스 관리 10. 사이트 분석 보고서보기" + echo "1. 도메인 이름 인증서 적용/업데이트 2. 사이트 도메인 이름 복제" + echo "3. 사이트 캐시 지우기 4. 관련 사이트 생성" + echo "5. 접속 로그 보기 6. 오류 로그 보기" + echo "7. 전역 구성 편집 8. 사이트 구성 편집" + echo "9. 사이트 데이터베이스 관리 10. 사이트 분석 보고서 보기" echo "------------------------" - echo "20. 지정된 사이트 데이터를 삭제합니다" + echo "20. 특정 사이트 데이터 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "도메인 이름 인증서를 신청하십시오" - read -e -p "도메인 이름을 입력하십시오 :" yuming + send_stats "도메인 이름 인증서 신청" + read -e -p "도메인 이름을 입력하세요:" yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "사이트 도메인 이름을 변경하십시오" - echo -e "${gl_hong}적극 권장 :${gl_bai}먼저 전체 사이트 데이터를 백업 한 다음 사이트 도메인 이름을 변경하십시오!" - read -e -p "이전 도메인 이름을 입력하십시오 :" oddyuming - read -e -p "새 도메인 이름을 입력하십시오 :" yuming + send_stats "복제 사이트 도메인 이름" + read -e -p "이전 도메인 이름을 입력하세요:" oddyuming + read -e -p "새 도메인 이름을 입력하세요:" yuming install_certbot install_ssltls certs_status - # MySQL 교체 - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3420,19 +3825,16 @@ ldnmp_web_status() { done done - # 웹 사이트 디렉토리 교체 - mv /home/web/html/$oddyuming /home/web/html/$yuming + # 웹사이트 디렉토리 교체 + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3441,10 +3843,10 @@ ldnmp_web_status() { web_cache ;; 4) - send_stats "관련 사이트를 만듭니다" - echo -e "액세스 용 기존 사이트의 새 도메인 이름을 연결하십시오." - read -e -p "기존 도메인 이름을 입력하십시오 :" oddyuming - read -e -p "새 도메인 이름을 입력하십시오 :" yuming + send_stats "연결된 사이트 만들기" + echo -e "액세스하려면 새 도메인 이름을 기존 사이트에 연결하세요." + read -e -p "기존 도메인 이름을 입력하세요:" oddyuming + read -e -p "새 도메인 이름을 입력하세요:" yuming install_certbot install_ssltls certs_status @@ -3458,17 +3860,17 @@ ldnmp_web_status() { ;; 5) - send_stats "액세스 로그를 봅니다" + send_stats "접속 로그 보기" tail -n 200 /home/web/log/nginx/access.log break_end ;; 6) - send_stats "오류 로그를 봅니다" + send_stats "오류 로그 보기" tail -n 200 /home/web/log/nginx/error.log break_end ;; 7) - send_stats "글로벌 구성 편집" + send_stats "전역 구성 편집" install nano nano /home/web/nginx.conf docker exec nginx nginx -s reload @@ -3476,7 +3878,7 @@ ldnmp_web_status() { 8) send_stats "사이트 구성 편집" - read -e -p "사이트 구성을 편집하려면 편집 할 도메인 이름을 입력하십시오." yuming + read -e -p "사이트 구성을 편집하려면 편집하려는 도메인 이름을 입력하십시오:" yuming install nano nano /home/web/conf.d/$yuming.conf docker exec nginx nginx -s reload @@ -3486,14 +3888,14 @@ ldnmp_web_status() { break_end ;; 10) - send_stats "사이트 데이터를 봅니다" + send_stats "사이트 데이터 보기" install goaccess goaccess --log-format=COMBINED /home/web/log/nginx/access.log ;; 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3508,7 +3910,7 @@ ldnmp_web_status() { check_panel_app() { if $lujing > /dev/null 2>&1; then - check_panel="${gl_lv}已安装${gl_bai}" + check_panel="${gl_lv}설치됨${gl_bai}" else check_panel="" fi @@ -3522,32 +3924,38 @@ while true; do clear check_panel_app echo -e "$panelname $check_panel" - echo "${panelname}요즘 인기 있고 강력한 운영 및 유지 관리 패널입니다." - echo "공식 웹 사이트 소개 :$panelurl " + echo "${panelname}대중적이고 강력한 운영 및 유지 관리 관리 패널입니다." + echo "공식 웹사이트 소개:$panelurl " echo "" echo "------------------------" echo "1. 설치 2. 관리 3. 제거" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) check_disk_space 1 install wget iptables_open panel_app_install + + add_app_id send_stats "${panelname}설치하다" ;; 2) panel_app_manage + + add_app_id send_stats "${panelname}제어" ;; 3) panel_app_uninstall - send_stats "${panelname}제거하십시오" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "${panelname}제거" ;; *) break @@ -3563,9 +3971,9 @@ done check_frp_app() { if [ -d "/home/frp/" ]; then - check_frp="${gl_lv}已安装${gl_bai}" + check_frp="${gl_lv}설치됨${gl_bai}" else - check_frp="${gl_hui}未安装${gl_bai}" + check_frp="${gl_hui}설치되지 않음${gl_bai}" fi } @@ -3591,8 +3999,8 @@ donlond_frp() { generate_frps_config() { - send_stats "FRP 서버를 설치하십시오" - # 임의의 포트 및 자격 증명을 생성합니다 + send_stats "FRP 서버 설치" + # 임의의 포트 및 자격 증명 생성 local bind_port=8055 local dashboard_port=8056 local token=$(openssl rand -hex 16) @@ -3613,17 +4021,17 @@ EOF donlond_frp frps - # 출력 생성 정보 + # 생성된 정보를 출력 ip_address echo "------------------------" - echo "클라이언트 배포에 필요한 매개 변수" - echo "서비스 IP :$ipv4_address" + echo "클라이언트 배포에 필요한 매개변수" + echo "서비스 IP:$ipv4_address" echo "token: $token" echo echo "FRP 패널 정보" - echo "FRP 패널 주소 : http : //$ipv4_address:$dashboard_port" - echo "FRP 패널 사용자 이름 :$dashboard_user" - echo "FRP 패널 비밀번호 :$dashboard_pwd" + echo "FRP 패널 주소: http://$ipv4_address:$dashboard_port" + echo "FRP 패널 사용자 이름:$dashboard_user" + echo "FRP 패널 비밀번호:$dashboard_pwd" echo open_port 8055 8056 @@ -3633,9 +4041,9 @@ EOF configure_frpc() { - send_stats "FRP 클라이언트를 설치하십시오" - read -e -p "외부 네트워크 도킹 IP를 입력하십시오." server_addr - read -e -p "외부 네트워크 도킹 토큰을 입력하십시오." token + send_stats "FRP 클라이언트 설치" + read -e -p "외부 네트워크 도킹 IP를 입력하세요." server_addr + read -e -p "외부 네트워크 도킹 토큰을 입력하세요." token echo mkdir -p /home/frp @@ -3655,17 +4063,17 @@ EOF } add_forwarding_service() { - send_stats "FRP 인트라넷 서비스를 추가하십시오" - # 사용자에게 서비스 이름 및 전달 정보를 입력하라는 메시지 - read -e -p "서비스 이름을 입력하십시오 :" service_name - read -e -p "전달 유형 (TCP/UDP)을 입력하십시오 [기본 TCP 입력] :" service_type + send_stats "FRP 인트라넷 서비스 추가" + # 사용자에게 서비스 이름 및 전달 정보를 묻는 메시지를 표시합니다. + read -e -p "서비스 이름을 입력하세요:" service_name + read -e -p "전달 유형(tcp/udp)을 입력하십시오. [기본값을 tcp로 입력]:" service_type local service_type=${service_type:-tcp} - read -e -p "인트라넷 IP를 입력하십시오 [기본값 127.0.0.1 입력] : :" local_ip + read -e -p "인트라넷 IP를 입력하십시오. [Enter를 누르면 기본값은 127.0.0.1입니다]:" local_ip local local_ip=${local_ip:-127.0.0.1} - read -e -p "인트라넷 포트를 입력하십시오 :" local_port - read -e -p "외부 네트워크 포트를 입력하십시오 :" remote_port + read -e -p "인트라넷 포트를 입력하십시오:" local_port + read -e -p "외부 네트워크 포트를 입력하세요:" remote_port - # 구성 파일에 사용자 입력을 쓰십시오 + # 구성 파일에 사용자 입력 쓰기 cat <> /home/frp/frpc.toml [$service_name] type = ${service_type} @@ -3675,8 +4083,8 @@ remote_port = ${remote_port} EOF - # 출력 생성 정보 - echo "제공하다$service_namefrpc.toml에 성공적으로 추가되었습니다" + # 생성된 정보를 출력 + echo "제공하다$service_namefrpc.toml에 성공적으로 추가되었습니다." docker restart frpc @@ -3687,12 +4095,12 @@ EOF delete_forwarding_service() { - send_stats "FRP 인트라넷 서비스를 삭제하십시오" - # 삭제 해야하는 서비스 이름을 입력하라는 메시지 - read -e -p "삭제 해야하는 서비스 이름을 입력하십시오." service_name - # SED를 사용하여 서비스 및 관련 구성을 삭제하십시오. + send_stats "FRP 인트라넷 서비스 삭제" + # 삭제해야 하는 서비스 이름을 입력하라는 메시지를 사용자에게 표시합니다. + read -e -p "삭제할 서비스 이름을 입력하세요:" service_name + # sed를 사용하여 서비스 및 관련 구성 삭제 sed -i "/\[$service_name\]/,/^$/d" /home/frp/frpc.toml - echo "제공하다$service_namefrpc.toml에서 성공적으로 삭제되었습니다" + echo "제공하다$service_namefrpc.toml에서 성공적으로 제거되었습니다." docker restart frpc @@ -3702,8 +4110,8 @@ delete_forwarding_service() { list_forwarding_services() { local config_file="$1" - # 헤더를 인쇄하십시오 - printf "%-20s %-25s %-30s %-10s\n" "服务名称" "内网地址" "外网地址" "协议" + # 헤더 인쇄 + printf "%-20s %-25s %-30s %-10s\n" "서비스 이름" "인트라넷 주소" "외부 네트워크 주소" "규약" awk ' BEGIN { @@ -3723,7 +4131,7 @@ list_forwarding_services() { } /^\[.*\]/ { - # 서비스 정보가있는 경우 새 서비스를 처리하기 전에 현재 서비스를 인쇄하십시오. + # 서비스 정보가 이미 존재하는 경우 새 서비스를 처리하기 전에 현재 서비스를 인쇄하십시오. if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3732,11 +4140,11 @@ list_forwarding_services() { type } - # 현재 서비스 이름을 업데이트하십시오 + # 현재 서비스 이름 업데이트 if ($1 != "[common]") { gsub(/[\[\]]/, "", $1) current_service=$1 - # 이전 값을 지우십시오 + # 이전 값 지우기 local_ip="" local_port="" remote_port="" @@ -3765,7 +4173,7 @@ list_forwarding_services() { } END { - # 마지막 서비스에 대한 정보를 인쇄하십시오 + # 마지막 서비스에 대한 정보 인쇄 if (current_service != "" && current_service != "common" && local_ip != "" && local_port != "") { printf "%-16s %-21s %-26s %-10s\n", \ current_service, \ @@ -3778,17 +4186,17 @@ list_forwarding_services() { -# FRP 서버 포트를 가져옵니다 +# FRP 서버 포트 가져오기 get_frp_ports() { mapfile -t ports < <(ss -tulnape | grep frps | awk '{print $5}' | awk -F':' '{print $NF}' | sort -u) } -# 액세스 주소를 생성합니다 +# 액세스 주소 생성 generate_access_urls() { - # 모든 포트를 먼저 얻으십시오 + # 먼저 모든 포트를 확보하십시오. get_frp_ports - # 8055/8056 이외의 포트가 있는지 확인하십시오 + # 8055/8056 이외의 포트가 있는지 확인하세요. local has_valid_ports=false for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3797,18 +4205,18 @@ generate_access_urls() { fi done - # 유효한 포트가있을 때만 제목과 콘텐츠 표시 + # 유효한 포트가 있는 경우에만 제목과 내용 표시 if [ "$has_valid_ports" = true ]; then - echo "FRP 서비스 외부 액세스 주소 :" + echo "FRP 서비스 외부 액세스 주소:" - # 프로세스 IPv4 주소 + # IPv4 주소 처리 for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then echo "http://${ipv4_address}:${port}" fi done - # Process IPv6 주소 (현재 경우) + # IPv6 주소가 있는 경우 처리 if [ -n "$ipv6_address" ]; then for port in "${ports[@]}"; do if [[ $port != "8055" && $port != "8056" ]]; then @@ -3845,6 +4253,7 @@ frps_main_ports() { frps_panel() { send_stats "FRP 서버" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3852,9 +4261,9 @@ frps_panel() { check_frp_app check_docker_image_update $docker_name echo -e "FRP 서버$check_frp $update_status" - echo "FRP 인트라넷 침투 서비스 환경을 구축하여 인터넷에 공개 IP없이 장치를 노출시킵니다." - echo "공식 웹 사이트 소개 : https://github.com/fatedier/frp/" - echo "비디오 교육 : https://www.bilibili.com/video/bv1ymw6e2ewl?t=124.0" + echo "FRP 인트라넷 침투 서비스 환경을 구축하고 공인 IP가 없는 장치를 인터넷에 노출시킵니다." + echo "공식 홈페이지 소개: https://github.com/fatedier/frp/" + echo "비디오 튜토리얼: https://www.bilibili.com/video/BV1yMw6e2EwL?t=124.0" if [ -d "/home/frp/" ]; then check_docker_app_ip frps_main_ports @@ -3863,18 +4272,20 @@ frps_panel() { echo "------------------------" echo "1. 설치 2. 업데이트 3. 제거" echo "------------------------" - echo "5. 인트라넷 서비스에 대한 도메인 이름 액세스 6. 도메인 이름 액세스 삭제" + echo "5. 인트라넷 서비스 도메인 이름 접근 6. 도메인 이름 접근 삭제" echo "------------------------" - echo "7. IP+ 포트 액세스 허용 8. 블록 IP+ 포트 액세스" + echo "7. IP+포트 접근 허용 8. IP+포트 접근 차단" echo "------------------------" - echo "00. 서비스 상태 새로 고침 0. 이전 메뉴로 돌아갑니다." + echo "00. 서비스 상태 새로고침 0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) install jq grep ss install_docker generate_frps_config + + add_app_id echo "FRP 서버가 설치되었습니다" ;; 2) @@ -3883,6 +4294,8 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps + + add_app_id echo "FRP 서버가 업데이트되었습니다" ;; 3) @@ -3893,37 +4306,38 @@ frps_panel() { close_port 8055 8056 - echo "앱이 제거되었습니다" + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "앱이 제거되었습니다." ;; 5) - echo "리버스 인트라넷 침투 서비스를 도메인 이름 액세스로 향합니다" - send_stats "외부 도메인 이름에 대한 FRP 액세스" + echo "도메인 이름 액세스에 대한 역인트라넷 침투 서비스" + send_stats "FRP 외부 도메인 이름 액세스" add_yuming - read -e -p "인트라넷 침투 서비스 포트를 입력하십시오 :" frps_port + read -e -p "인트라넷 침투 서비스 포트를 입력하십시오:" frps_port ldnmp_Proxy ${yuming} 127.0.0.1 ${frps_port} block_host_port "$frps_port" "$ipv4_address" ;; 6) - echo "도메인 이름 형식 example.com은 https : //와 함께 제공되지 않습니다." + echo "https://가 없는 도메인 이름 형식 example.com" web_del ;; 7) send_stats "IP 액세스 허용" - read -e -p "해제 할 포트를 입력하십시오." frps_port + read -e -p "해제해야 하는 포트를 입력하세요." frps_port clear_host_port_rules "$frps_port" "$ipv4_address" ;; 8) - send_stats "IP 액세스를 차단하십시오" - echo "반세기 도메인 이름에 액세스 한 경우이 기능을 사용하여 IP+ 포트 액세스를 차단할 수 있습니다." - read -e -p "차단 해야하는 포트를 입력하십시오." frps_port + send_stats "IP 접근 차단" + echo "역방향 도메인 이름 접근이 있는 경우, 이 기능을 사용하면 IP+포트 접근을 차단할 수 있어 더욱 안전합니다." + read -e -p "차단할 포트를 입력하세요:" frps_port block_host_port "$frps_port" "$ipv4_address" ;; 00) - send_stats "FRP 서비스 상태를 새로 고치십시오" - echo "FRP 서비스 상태가 새로 고쳐졌습니다" + send_stats "FRP 서비스 상태 새로 고침" + echo "FRP 서비스 상태가 새로 고쳐졌습니다." ;; *) @@ -3937,6 +4351,7 @@ frps_panel() { frpc_panel() { send_stats "FRP 클라이언트" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do @@ -3944,9 +4359,9 @@ frpc_panel() { check_frp_app check_docker_image_update $docker_name echo -e "FRP 클라이언트$check_frp $update_status" - echo "서버로 도킹, 도킹 후 인터넷 액세스에 인트라넷 침투 서비스를 만들 수 있습니다." - echo "공식 웹 사이트 소개 : https://github.com/fatedier/frp/" - echo "비디오 교육 : https://www.bilibili.com/video/bv1ymw6e2ewl?t=173.9" + echo "서버에 연결하세요. 연결 후에는 인트라넷 침투 서비스를 만들어 인터넷에 액세스할 수 있습니다." + echo "공식 홈페이지 소개: https://github.com/fatedier/frp/" + echo "비디오 튜토리얼: https://www.bilibili.com/video/BV1yMw6e2EwL?t=173.9" echo "------------------------" if [ -d "/home/frp/" ]; then [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml @@ -3956,16 +4371,18 @@ frpc_panel() { echo "------------------------" echo "1. 설치 2. 업데이트 3. 제거" echo "------------------------" - echo "4. 외부 서비스 추가 5. 외부 서비스 삭제 6. 서비스 구성 수동으로 서비스 구성" + echo "4. 외부 서비스 추가 5. 외부 서비스 삭제 6. 서비스 수동 구성" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) install jq grep ss install_docker configure_frpc + + add_app_id echo "FRP 클라이언트가 설치되었습니다" ;; 2) @@ -3974,7 +4391,9 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc - echo "FRP 클라이언트가 업데이트되었습니다" + + add_app_id + echo "FRP 클라이언트가 업데이트되었습니다." ;; 3) @@ -3983,7 +4402,9 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 - echo "앱이 제거되었습니다" + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "앱이 제거되었습니다." ;; 4) @@ -4013,6 +4434,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4022,68 +4444,74 @@ yt_menu_pro() { while true; do if [ -x "/usr/local/bin/yt-dlp" ]; then - local YTDLP_STATUS="${gl_lv}已安装${gl_bai}" + local YTDLP_STATUS="${gl_lv}설치됨${gl_bai}" else - local YTDLP_STATUS="${gl_hui}未安装${gl_bai}" + local YTDLP_STATUS="${gl_hui}설치되지 않음${gl_bai}" fi clear - send_stats "YT-DLP 다운로드 도구" + send_stats "yt-dlp 다운로드 도구" echo -e "yt-dlp $YTDLP_STATUS" - echo -e "YT-DLP는 YouTube, Bilibili, Twitter 등을 포함한 수천 개의 사이트를 지원하는 강력한 비디오 다운로드 도구입니다." - echo -e "공식 웹 사이트 주소 : https://github.com/yt-dlp/yt-dlp" + echo -e "yt-dlp는 YouTube, Bilibili, Twitter 등과 같은 수천 개의 사이트를 지원하는 강력한 비디오 다운로드 도구입니다." + echo -e "공식 홈페이지 주소: https://github.com/yt-dlp/yt-dlp" echo "-------------------------" - echo "다운로드 된 비디오 목록 :" + echo "다운로드한 동영상 목록:" ls -td "$VIDEO_DIR"/*/ 2>/dev/null || echo "(아직 없음)" echo "-------------------------" echo "1. 설치 2. 업데이트 3. 제거" echo "-------------------------" - echo "5. 단일 비디오 다운로드 6. 배치 비디오 다운로드 7. 사용자 정의 매개 변수 다운로드" - echo "8. MP3 오디오 9. 비디오 디렉토리 삭제 10. 쿠키 관리 (개발 중)" + echo "5. 단일 비디오 다운로드 6. 일괄 비디오 다운로드 7. 사용자 정의 매개변수 다운로드" + echo "8. MP3 오디오로 다운로드 9. 비디오 디렉터리 삭제 10. 쿠키 관리(개발 중)" echo "-------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "-------------------------" - read -e -p "옵션 번호를 입력하십시오 :" choice + read -e -p "옵션 번호를 입력하세요:" choice case $choice in 1) - send_stats "yt-dlp 설치 ..." - echo "yt-dlp 설치 ..." + send_stats "yt-dlp 설치 중..." + echo "yt-dlp 설치 중..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp - echo "설치가 완료되었습니다. 계속하려면 키를 누르십시오 ..." + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id + echo "설치가 완료되었습니다. 계속하려면 아무 키나 누르세요..." read ;; 2) - send_stats "yt-dlp 업데이트 ..." - echo "yt-dlp 업데이트 ..." - sudo yt-dlp -U - echo "업데이트가 완료되었습니다. 계속하려면 키를 누르십시오 ..." + send_stats "yt-dlp 업데이트 중..." + echo "yt-dlp 업데이트 중..." + yt-dlp -U + + add_app_id + echo "업데이트가 완료되었습니다. 계속하려면 아무 키나 누르세요..." read ;; 3) - send_stats "yt-dlp 제거 ..." - echo "yt-dlp 제거 ..." - sudo rm -f /usr/local/bin/yt-dlp - echo "제거가 완료되었습니다. 계속하려면 키를 누르십시오 ..." + send_stats "yt-dlp 제거 중..." + echo "yt-dlp 제거 중..." + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "제거가 완료되었습니다. 계속하려면 아무 키나 누르세요..." read ;; 5) send_stats "단일 비디오 다운로드" - read -e -p "비디오 링크를 입력하십시오 :" url + read -e -p "동영상 링크를 입력하세요:" url yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "다운로드가 완료되면 키를 눌러 계속하십시오 ..." ;; + read -e -p "다운로드가 완료되었습니다. 계속하려면 아무 키나 누르세요..." ;; 6) - send_stats "배치 비디오 다운로드" + send_stats "일괄 비디오 다운로드" install nano if [ ! -f "$URL_FILE" ]; then - echo -e "# 여러 비디오 링크 주소를 입력하십시오 \ n# https://www.bilibili.com/bangumi/play/ep733316?spm_id_from=333.337.0.0&from_spmid=666.25.episode.0" > "$URL_FILE" + echo -e "# 여러 개의 동영상 링크 주소를 입력하세요\n# https://www.bilibili.com/bangumi/play/ep733316?spm_id_from=333.337.0.0&from_spmid=666.25.episode.0" > "$URL_FILE" fi nano $URL_FILE - echo "이제 배치 다운로드를 시작하십시오 ..." + echo "지금 일괄 다운로드를 시작하세요..." yt-dlp -P "$VIDEO_DIR" -f "bv*+ba/b" --merge-output-format mp4 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ @@ -4091,31 +4519,31 @@ yt_menu_pro() { -a "$URL_FILE" \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "배치 다운로드가 완료되었습니다. 키를 눌러 계속하십시오 ..." ;; + read -e -p "일괄 다운로드가 완료되었습니다. 계속하려면 아무 키나 누르세요..." ;; 7) send_stats "맞춤형 비디오 다운로드" - read -e -p "전체 YT-DLP 매개 변수를 입력하십시오 (YT-DLP 제외) :" custom + read -e -p "전체 yt-dlp 매개변수를 입력하세요(yt-dlp 제외)." custom yt-dlp -P "$VIDEO_DIR" $custom \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites - read -e -p "실행이 완료되면 키를 눌러 계속하십시오 ..." ;; + read -e -p "실행이 완료되었습니다. 계속하려면 아무 키나 누르세요..." ;; 8) send_stats "MP3 다운로드" - read -e -p "비디오 링크를 입력하십시오 :" url + read -e -p "동영상 링크를 입력하세요:" url yt-dlp -P "$VIDEO_DIR" -x --audio-format mp3 \ --write-subs --sub-langs all \ --write-thumbnail --embed-thumbnail \ --write-info-json \ -o "$VIDEO_DIR/%(title)s/%(title)s.%(ext)s" \ --no-overwrites --no-post-overwrites "$url" - read -e -p "오디오 다운로드가 완료되었습니다. 키를 누르면 계속하십시오 ..." ;; + read -e -p "오디오 다운로드가 완료되었습니다. 계속하려면 아무 키나 누르세요..." ;; 9) - send_stats "비디오 삭제" - read -e -p "삭제 비디오의 이름을 입력하십시오." rmdir + send_stats "동영상 삭제" + read -e -p "삭제된 동영상의 이름을 입력하세요:" rmdir rm -rf "$VIDEO_DIR/$rmdir" ;; *) @@ -4151,7 +4579,7 @@ set_timedate() { -# DPKG 인터럽트 문제를 수정하십시오 +# dpkg 중단 문제 수정 fix_dpkg() { pkill -9 -f 'apt|dpkg' rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock @@ -4160,7 +4588,7 @@ fix_dpkg() { linux_update() { - echo -e "${gl_huang}시스템 업데이트 ...${gl_bai}" + echo -e "${gl_huang}시스템 업데이트 진행 중...${gl_bai}" if command -v dnf &>/dev/null; then dnf -y update elif command -v yum &>/dev/null; then @@ -4179,7 +4607,7 @@ linux_update() { elif command -v opkg &>/dev/null; then opkg update else - echo "알 수없는 패키지 관리자!" + echo "알 수 없는 패키지 관리자입니다!" return fi } @@ -4187,7 +4615,7 @@ linux_update() { linux_clean() { - echo -e "${gl_huang}시스템 정리 ...${gl_bai}" + echo -e "${gl_huang}시스템 청소 진행 중...${gl_bai}" if command -v dnf &>/dev/null; then rpm --rebuilddb dnf autoremove -y @@ -4216,13 +4644,13 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v apk &>/dev/null; then - echo "패키지 관리자 캐시 청소 ..." + echo "패키지 관리자 캐시 정리..." apk cache clean - echo "시스템 로그 삭제 ..." + echo "시스템 로그 삭제..." rm -rf /var/log/* - echo "APK 캐시 삭제 ..." + echo "APK 캐시 삭제..." rm -rf /var/cache/apk/* - echo "임시 파일 삭제 ..." + echo "임시 파일 삭제..." rm -rf /tmp/* elif command -v pacman &>/dev/null; then @@ -4240,23 +4668,23 @@ linux_clean() { journalctl --vacuum-size=500M elif command -v opkg &>/dev/null; then - echo "시스템 로그 삭제 ..." + echo "시스템 로그 삭제..." rm -rf /var/log/* - echo "임시 파일 삭제 ..." + echo "임시 파일 삭제..." rm -rf /tmp/* elif command -v pkg &>/dev/null; then - echo "사용하지 않는 의존성 정리 ..." + echo "사용하지 않는 종속성을 정리합니다..." pkg autoremove -y - echo "패키지 관리자 캐시 청소 ..." + echo "패키지 관리자 캐시 정리..." pkg clean -y - echo "시스템 로그 삭제 ..." + echo "시스템 로그 삭제..." rm -rf /var/log/* - echo "임시 파일 삭제 ..." + echo "임시 파일 삭제..." rm -rf /tmp/* else - echo "알 수없는 패키지 관리자!" + echo "알 수 없는 패키지 관리자입니다!" return fi return @@ -4266,9 +4694,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4278,8 +4705,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4291,6 +4718,13 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } @@ -4299,23 +4733,23 @@ root_use send_stats "DNS 최적화" while true; do clear - echo "DNS 주소를 최적화합니다" + echo "DNS 주소 최적화" echo "------------------------" echo "현재 DNS 주소" cat /etc/resolv.conf echo "------------------------" echo "" - echo "1. 외국 DNS 최적화 :" + echo "1. 외국 DNS 최적화:" echo " v4: 1.1.1.1 8.8.8.8" echo " v6: 2606:4700:4700::1111 2001:4860:4860::8888" - echo "2. 국내 DNS 최적화 :" + echo "2. 국내 DNS 최적화:" echo " v4: 223.5.5.5 183.60.83.19" echo " v6: 2400:3200::1 2400:da00::6666" - echo "3. DNS 구성을 수동으로 편집합니다" + echo "3. DNS 구성을 수동으로 편집" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" Limiting + read -e -p "선택사항을 입력하세요:" Limiting case "$Limiting" in 1) local dns1_ipv4="1.1.1.1" @@ -4335,8 +4769,10 @@ while true; do ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf - send_stats "DNS 구성을 수동으로 편집합니다" + chattr +i /etc/resolv.conf + send_stats "DNS 구성을 수동으로 편집" ;; *) break @@ -4359,13 +4795,13 @@ correct_ssh_config() { local sshd_config="/etc/ssh/sshd_config" - # PasswordAuthentication이 발견되면 예로 설정하십시오 + # 발견된 경우 PasswordAuthentication이 yes로 설정되어 있습니다. if grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" fi - # 발견 된 경우 PubKeyAuthentication이 예로 설정됩니다 + # 발견된 경우 PubkeyAuthentication이 yes로 설정되어 있습니다. if grep -Eq "^PubkeyAuthentication\s+yes" "$sshd_config"; then sed -i -e 's/^\s*#\?\s*PermitRootLogin .*/PermitRootLogin prohibit-password/' \ -e 's/^\s*#\?\s*PasswordAuthentication .*/PasswordAuthentication no/' \ @@ -4373,7 +4809,7 @@ correct_ssh_config() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' "$sshd_config" fi - # PasswordAuthentication 또는 PubKeyAuthentication이 일치하지 않는 경우 기본값을 설정하십시오. + # PasswordAuthentication과 PubkeyAuthentication이 모두 일치하지 않는 경우 기본값을 설정합니다. if ! grep -Eq "^PasswordAuthentication\s+yes" "$sshd_config" && ! grep -Eq "^PubkeyAuthentication\s+yes" "$sshd_config"; then sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' "$sshd_config" sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' "$sshd_config" @@ -4384,7 +4820,7 @@ correct_ssh_config() { new_ssh_port() { - # 백업 SSH 구성 파일 + # SSH 구성 파일 백업 cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sed -i 's/^\s*#\?\s*Port/Port/' /etc/ssh/sshd_config @@ -4397,7 +4833,7 @@ new_ssh_port() { open_port $new_port remove iptables-persistent ufw firewalld iptables-services > /dev/null 2>&1 - echo "SSH 포트는 다음으로 수정되었습니다.$new_port" + echo "SSH 포트가 다음과 같이 수정되었습니다.$new_port" sleep 1 @@ -4415,7 +4851,7 @@ add_sshkey() { chmod 600 ~/.ssh/authorized_keys ip_address - echo -e "개인 키 정보가 생성되었습니다. 복사하고 저장하십시오.${gl_huang}${ipv4_address}_ssh.key${gl_bai}향후 SSH 로그인 파일" + echo -e "개인키 정보가 생성되었습니다. 꼭 복사해서 저장하세요. 다음과 같이 저장될 수 있습니다.${gl_huang}${ipv4_address}_ssh.key${gl_bai}향후 SSH 로그인을 위한 파일" echo "--------------------------------" cat ~/.ssh/sshkey @@ -4427,17 +4863,17 @@ add_sshkey() { -e 's/^\s*#\?\s*ChallengeResponseAuthentication .*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}루트 프라이빗 키 로그인이 활성화되고 루트 비밀번호 로그인이 닫히고 재 연결이 적용됩니다.${gl_bai}" + echo -e "${gl_lv}ROOT 개인키 로그인이 활성화되어 있고, ROOT 비밀번호 로그인이 비활성화되어 재접속이 적용됩니다.${gl_bai}" } import_sshkey() { - read -e -p "SSH 공개 키 내용을 입력하십시오 (일반적으로 'SSH-RSA'또는 'SSH-ED25519'로 시작) :" public_key + read -e -p "SSH 공개 키(일반적으로 'ssh-rsa' 또는 'ssh-ed25519'로 시작)의 내용을 입력하세요." public_key if [[ -z "$public_key" ]]; then - echo -e "${gl_hong}오류 : 공개 키 컨텐츠가 입력되지 않았습니다.${gl_bai}" + echo -e "${gl_hong}오류: 공개 키 내용이 입력되지 않았습니다.${gl_bai}" return 1 fi @@ -4455,7 +4891,7 @@ import_sshkey() { rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh - echo -e "${gl_lv}공개 키가 성공적으로 가져 왔고 루트 개인 키 로그인이 활성화되었고 루트 비밀번호 로그인이 닫히고 재 연결이 적용됩니다.${gl_bai}" + echo -e "${gl_lv}공개 키를 성공적으로 가져왔고 ROOT 개인 키 로그인이 활성화되었으며 ROOT 비밀번호 로그인이 종료되었습니다. 다시 연결이 적용됩니다.${gl_bai}" } @@ -4464,26 +4900,26 @@ import_sshkey() { add_sshpasswd() { -echo "루트 비밀번호를 설정하십시오" +echo "루트 비밀번호를 설정하세요" passwd sed -i 's/^\s*#\?\s*PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config; sed -i 's/^\s*#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config; rm -rf /etc/ssh/sshd_config.d/* /etc/ssh/ssh_config.d/* restart_ssh -echo -e "${gl_lv}루트 로그인이 설정되었습니다!${gl_bai}" +echo -e "${gl_lv}ROOT 로그인 설정이 완료되었습니다!${gl_bai}" } root_use() { clear -[ "$EUID" -ne 0 ] && echo -e "${gl_huang}힌트:${gl_bai}이 기능은 루트 사용자가 실행해야합니다!" && break_end && kejilion +[ "$EUID" -ne 0 ] && echo -e "${gl_huang}힌트:${gl_bai}이 기능을 실행하려면 루트 사용자가 필요합니다!" && break_end && kejilion } dd_xitong() { - send_stats "시스템을 다시 설치하십시오" + send_stats "시스템 재설치" dd_xitong_MollyLau() { wget --no-check-certificate -qO InstallNET.sh "${gh_proxy}raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh" && chmod a+x InstallNET.sh @@ -4494,44 +4930,47 @@ dd_xitong() { } dd_xitong_1() { - echo -e "재설치 후 초기 사용자 이름 :${gl_huang}root${gl_bai}초기 비밀번호 :${gl_huang}LeitboGi0ro${gl_bai}초기 포트 :${gl_huang}22${gl_bai}" - echo -e "계속하려면 키를 누르십시오 ..." + echo -e "재설치 후 초기 사용자 이름:${gl_huang}root${gl_bai}초기 비밀번호:${gl_huang}LeitboGi0ro${gl_bai}초기 포트:${gl_huang}22${gl_bai}" + echo -e "${gl_huang}재설치 후에는 초기 비밀번호를 적시에 변경하여 폭력적인 침입을 방지하시기 바랍니다. 비밀번호를 변경하려면 명령줄에 passwd를 입력하세요.${gl_bai}" + echo -e "계속하려면 아무 키나 누르세요..." read -n 1 -s -r -p "" install wget dd_xitong_MollyLau } dd_xitong_2() { - echo -e "재설치 후 초기 사용자 이름 :${gl_huang}Administrator${gl_bai}초기 비밀번호 :${gl_huang}Teddysun.com${gl_bai}초기 포트 :${gl_huang}3389${gl_bai}" - echo -e "계속하려면 키를 누르십시오 ..." + echo -e "재설치 후 초기 사용자 이름:${gl_huang}Administrator${gl_bai}초기 비밀번호:${gl_huang}Teddysun.com${gl_bai}초기 포트:${gl_huang}3389${gl_bai}" + echo -e "계속하려면 아무 키나 누르세요..." read -n 1 -s -r -p "" install wget dd_xitong_MollyLau } dd_xitong_3() { - echo -e "재설치 후 초기 사용자 이름 :${gl_huang}root${gl_bai}초기 비밀번호 :${gl_huang}123@@@${gl_bai}초기 포트 :${gl_huang}22${gl_bai}" - echo -e "계속하려면 키를 누르십시오 ..." + echo -e "재설치 후 초기 사용자 이름:${gl_huang}root${gl_bai}초기 비밀번호:${gl_huang}123@@@${gl_bai}초기 포트:${gl_huang}22${gl_bai}" + echo -e "계속하려면 아무 키나 누르세요..." read -n 1 -s -r -p "" dd_xitong_bin456789 } dd_xitong_4() { - echo -e "재설치 후 초기 사용자 이름 :${gl_huang}Administrator${gl_bai}초기 비밀번호 :${gl_huang}123@@@${gl_bai}초기 포트 :${gl_huang}3389${gl_bai}" - echo -e "계속하려면 키를 누르십시오 ..." + echo -e "재설치 후 초기 사용자 이름:${gl_huang}Administrator${gl_bai}초기 비밀번호:${gl_huang}123@@@${gl_bai}초기 포트:${gl_huang}3389${gl_bai}" + echo -e "계속하려면 아무 키나 누르세요..." read -n 1 -s -r -p "" dd_xitong_bin456789 } while true; do root_use - echo "시스템을 다시 설치하십시오" + echo "시스템 재설치" echo "--------------------------------" - echo -e "${gl_hong}알아채다:${gl_bai}다시 설치는 접촉을 잃을 위험이 있으며 걱정하는 사람들은 그것을주의해서 사용해야합니다. 재설치는 15 분이 걸릴 것으로 예상됩니다. 데이터를 미리 백업하십시오." - echo -e "${gl_hui}스크립트 지원을 위해 Mollylau 및 Bin456789에게 감사드립니다!${gl_bai} " + echo -e "${gl_hong}알아채다:${gl_bai}재설치 시 연결이 끊어질 수 있으니 걱정되시는 분들은 주의해서 사용해주세요. 재설치에는 약 15분 정도 소요될 예정이오니, 사전에 데이터를 백업해 주시기 바랍니다." + echo -e "${gl_hui}스크립트 지원을 해주신 bin456789 보스와 leitbogioro 보스에게 감사드립니다!${gl_bai} " + echo -e "${gl_hui}bin456789 프로젝트 주소: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro 프로젝트 주소: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4544,68 +4983,71 @@ dd_xitong() { echo "------------------------" echo "31. Alpine Linux 32. Arch Linux" echo "33. Kali Linux 34. openEuler" - echo "35. OpenSuse Tumbleweed 36. FNOS FEINIU 공개 베타 버전" + echo "35. openSUSE Tumbleweed 36. fnos Feiniu 공개 베타 버전" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "다시 설치할 시스템을 선택하십시오." sys_choice + read -e -p "다시 설치하려는 시스템을 선택하십시오:" sys_choice case "$sys_choice" in + + 1) - send_stats "데비안 12를 다시 설치하십시오" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "데비안 13 재설치" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "데비안 11을 다시 설치하십시오" + send_stats "데비안 12 다시 설치" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "데비안 10을 다시 설치하십시오" + send_stats "데비안 11 다시 설치" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "데비안 9를 다시 설치하십시오" + send_stats "데비안 10 다시 설치" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; 11) - send_stats "우분투 24.04를 다시 설치하십시오" + send_stats "우분투 24.04 다시 설치" dd_xitong_1 bash InstallNET.sh -ubuntu 24.04 reboot exit ;; 12) - send_stats "우분투 22.04를 다시 설치하십시오" + send_stats "우분투 22.04 다시 설치" dd_xitong_1 bash InstallNET.sh -ubuntu 22.04 reboot exit ;; 13) - send_stats "Ubuntu 20.04를 다시 설치하십시오" + send_stats "우분투 20.04 다시 설치" dd_xitong_1 bash InstallNET.sh -ubuntu 20.04 reboot exit ;; 14) - send_stats "우분투 18.04를 다시 설치하십시오" + send_stats "우분투 18.04 다시 설치" dd_xitong_1 bash InstallNET.sh -ubuntu 18.04 reboot @@ -4614,7 +5056,7 @@ dd_xitong() { 21) - send_stats "Rockylinux10을 다시 설치하십시오" + send_stats "rockylinux10 재설치" dd_xitong_3 bash reinstall.sh rocky reboot @@ -4622,7 +5064,7 @@ dd_xitong() { ;; 22) - send_stats "Rockylinux9를 다시 설치하십시오" + send_stats "rockylinux9 재설치" dd_xitong_3 bash reinstall.sh rocky 9 reboot @@ -4630,7 +5072,7 @@ dd_xitong() { ;; 23) - send_stats "Alma10을 다시 설치하십시오" + send_stats "alma10 재설치" dd_xitong_3 bash reinstall.sh almalinux reboot @@ -4638,7 +5080,7 @@ dd_xitong() { ;; 24) - send_stats "Alma9를 다시 설치하십시오" + send_stats "alma9 재설치" dd_xitong_3 bash reinstall.sh almalinux 9 reboot @@ -4646,7 +5088,7 @@ dd_xitong() { ;; 25) - send_stats "Oracle10을 다시 설치하십시오" + send_stats "oracle10 재설치" dd_xitong_3 bash reinstall.sh oracle reboot @@ -4654,7 +5096,7 @@ dd_xitong() { ;; 26) - send_stats "Oracle9를 다시 설치하십시오" + send_stats "oracle9 재설치" dd_xitong_3 bash reinstall.sh oracle 9 reboot @@ -4662,7 +5104,7 @@ dd_xitong() { ;; 27) - send_stats "Fedora42를 다시 설치하십시오" + send_stats "fedora42 재설치" dd_xitong_3 bash reinstall.sh fedora reboot @@ -4670,7 +5112,7 @@ dd_xitong() { ;; 28) - send_stats "Fedora41을 다시 설치하십시오" + send_stats "fedora41 재설치" dd_xitong_3 bash reinstall.sh fedora 41 reboot @@ -4678,7 +5120,7 @@ dd_xitong() { ;; 29) - send_stats "CentOS10을 다시 설치하십시오" + send_stats "centos10 재설치" dd_xitong_3 bash reinstall.sh centos 10 reboot @@ -4686,7 +5128,7 @@ dd_xitong() { ;; 30) - send_stats "CentOS9를 다시 설치하십시오" + send_stats "centos9 재설치" dd_xitong_3 bash reinstall.sh centos 9 reboot @@ -4694,7 +5136,7 @@ dd_xitong() { ;; 31) - send_stats "알파인을 다시 설치하십시오" + send_stats "알파인 재설치" dd_xitong_1 bash InstallNET.sh -alpine reboot @@ -4702,7 +5144,7 @@ dd_xitong() { ;; 32) - send_stats "아치를 다시 설치하십시오" + send_stats "아치 재설치" dd_xitong_3 bash reinstall.sh arch reboot @@ -4710,7 +5152,7 @@ dd_xitong() { ;; 33) - send_stats "칼리를 다시 설치하십시오" + send_stats "칼리 재설치" dd_xitong_3 bash reinstall.sh kali reboot @@ -4718,7 +5160,7 @@ dd_xitong() { ;; 34) - send_stats "Openeuler를 다시 설치하십시오" + send_stats "openeuler 다시 설치" dd_xitong_3 bash reinstall.sh openeuler reboot @@ -4726,7 +5168,7 @@ dd_xitong() { ;; 35) - send_stats "재설치 OpenSuse" + send_stats "Openuse 다시 설치" dd_xitong_3 bash reinstall.sh opensuse reboot @@ -4734,30 +5176,31 @@ dd_xitong() { ;; 36) - send_stats "비행 소부소" + send_stats "Feiniu 재설치" dd_xitong_3 bash reinstall.sh fnos reboot exit ;; - 41) - send_stats "Windows 11을 다시 설치하십시오" + send_stats "윈도우 11 재설치" dd_xitong_2 bash InstallNET.sh -windows 11 -lang "cn" reboot exit ;; + 42) dd_xitong_2 - send_stats "Windows 10을 다시 설치하십시오" + send_stats "윈도우 10 재설치" bash InstallNET.sh -windows 10 -lang "cn" reboot exit ;; + 43) - send_stats "Windows 7을 다시 설치하십시오" + send_stats "Windows7을 다시 설치하세요." dd_xitong_4 bash reinstall.sh windows --iso="https://drive.massgrave.dev/cn_windows_7_professional_with_sp1_x64_dvd_u_677031.iso" --image-name='Windows 7 PROFESSIONAL' reboot @@ -4765,29 +5208,31 @@ dd_xitong() { ;; 44) - send_stats "Windows Server 22를 다시 설치하십시오" + send_stats "Windows Server 25를 다시 설치하세요." dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "Windows Server 19를 다시 설치하십시오" + send_stats "윈도우 서버 22 재설치" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "Windows Server 16을 다시 설치하십시오" + send_stats "윈도우 서버 19 재설치" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; 47) - send_stats "Windows11 Arm을 다시 설치하십시오" + send_stats "windows11 ARM 재설치" dd_xitong_4 bash reinstall.sh dd --img https://r2.hotdog.eu.org/win11-arm-with-pagefile-15g.xz reboot @@ -4804,7 +5249,7 @@ dd_xitong() { bbrv3() { root_use - send_stats "BBRV3 관리" + send_stats "bbrv3 관리" local cpu_arch=$(uname -m) if [ "$cpu_arch" = "aarch64" ]; then @@ -4817,17 +5262,17 @@ bbrv3() { while true; do clear local kernel_version=$(uname -r) - echo "Xanmod의 BBRV3 커널을 설치했습니다" - echo "현재 커널 버전 :$kernel_version" + echo "xanmod의 BBRv3 커널이 설치되어 있습니다." + echo "현재 커널 버전:$kernel_version" echo "" echo "커널 관리" echo "------------------------" - echo "1. BBRV3 커널 업데이트 2. BBRV3 커널 제거" + echo "1. BBRv3 커널 업데이트 2. BBRv3 커널 제거" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) @@ -4837,7 +5282,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # 3 단계 : 저장소를 추가합니다 + # 3단계: 저장소 추가 echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4846,7 +5291,7 @@ bbrv3() { apt update -y apt install -y linux-xanmod-x64v$version - echo "Xanmod 커널이 업데이트되었습니다. 다시 시작한 후에도 적용됩니다" + echo "XanMod 커널이 업데이트되었습니다. 재시작 후 적용" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* @@ -4856,7 +5301,7 @@ bbrv3() { 2) apt purge -y 'linux-*xanmod1*' update-grub - echo "Xanmod 커널은 제거되었습니다. 다시 시작한 후에도 적용됩니다" + echo "XanMod 커널이 제거되었습니다. 재시작 후 적용" server_reboot ;; @@ -4869,14 +5314,13 @@ bbrv3() { else clear - echo "BBR3 가속도를 설정하십시오" - echo "비디오 소개 : https://www.bilibili.com/video/bv14k421x7bs?t=0.1" + echo "BBR3 가속 설정" + echo "영상 소개: https://www.bilibili.com/video/BV14K421x7BS?t=0.1" echo "------------------------------------------------" - echo "데비안/우분투 만 지원합니다" - echo "데이터를 백업하고 BBR3에서 Linux 커널을 업그레이드 할 수 있습니다." - echo "VPS는 512m 메모리를 가지고 있습니다. 메모리가 충분하지 않아 접점 누락을 방지하기 위해 1G 가상 메모리를 미리 추가하십시오!" + echo "데비안/우분투만 지원" + echo "데이터를 백업해 주시면 Linux 커널을 업그레이드하고 BBR3을 활성화하겠습니다." echo "------------------------------------------------" - read -e -p "계속할거야? (Y/N) :" choice + read -e -p "계속하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) @@ -4884,12 +5328,12 @@ bbrv3() { if [ -r /etc/os-release ]; then . /etc/os-release if [ "$ID" != "debian" ] && [ "$ID" != "ubuntu" ]; then - echo "현재 환경은이를 지원하지 않으며 데비안 및 우분투 시스템 만 지원합니다." + echo "현재 환경에서는 지원하지 않습니다. Debian 및 Ubuntu 시스템만 지원됩니다." break_end linux_Settings fi else - echo "운영 체제 유형을 결정할 수 없습니다" + echo "운영 체제 유형을 확인할 수 없습니다." break_end linux_Settings fi @@ -4900,7 +5344,7 @@ bbrv3() { # wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes wget -qO - ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg --yes - # 3 단계 : 저장소를 추가합니다 + # 3단계: 저장소 추가 echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list # version=$(wget -q https://dl.xanmod.org/check_x86-64_psabi.sh && chmod +x check_x86-64_psabi.sh && ./check_x86-64_psabi.sh | grep -oP 'x86-64-v\K\d+|x86-64-v\d+') @@ -4911,7 +5355,7 @@ bbrv3() { bbr_on - echo "Xanmod 커널이 설치되고 BBR3이 성공적으로 활성화됩니다. 다시 시작한 후에도 적용됩니다" + echo "XanMod 커널이 설치되고 BBR3이 성공적으로 활성화되었습니다. 재시작 후 적용" rm -f /etc/apt/sources.list.d/xanmod-release.list rm -f check_x86-64_psabi.sh* server_reboot @@ -4921,7 +5365,7 @@ bbrv3() { echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac fi @@ -4930,40 +5374,40 @@ bbrv3() { elrepo_install() { - # Elrepo GPG 공개 키를 가져 오십시오 - echo "Elrepo GPG 공개 키를 가져 오십시오 ..." + # ELRepo GPG 공개 키 가져오기 + echo "ELRepo GPG 공개 키 가져오기..." rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org - # 시스템 버전을 감지하십시오 + # 시스템 버전 확인 local os_version=$(rpm -q --qf "%{VERSION}" $(rpm -qf /etc/os-release) 2>/dev/null | awk -F '.' '{print $1}') local os_name=$(awk -F= '/^NAME/{print $2}' /etc/os-release) - # 지원되는 운영 체제에서 실행하십시오 + # 지원되는 운영 체제에서 실행되고 있는지 확인하세요. if [[ "$os_name" != *"Red Hat"* && "$os_name" != *"AlmaLinux"* && "$os_name" != *"Rocky"* && "$os_name" != *"Oracle"* && "$os_name" != *"CentOS"* ]]; then - echo "지원되지 않는 운영 체제 :$os_name" + echo "지원되지 않는 운영 체제:$os_name" break_end linux_Settings fi - # 감지 된 운영 체제 정보를 인쇄합니다 - echo "운영 체제 감지 :$os_name $os_version" - # 시스템 버전에 따라 해당 Elrepo 창고 구성을 설치하십시오. + # 감지된 운영 체제 정보 인쇄 + echo "감지된 운영 체제:$os_name $os_version" + # 시스템 버전에 따라 해당 ELRepo 창고 구성을 설치하십시오. if [[ "$os_version" == 8 ]]; then - echo "Elrepo 저장소 구성 (버전 8)을 설치하십시오 ..." + echo "ELRepo 저장소 구성(버전 8) 설치 중..." yum -y install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm elif [[ "$os_version" == 9 ]]; then - echo "Elrepo 저장소 구성 (버전 9)을 설치하십시오 ..." + echo "ELRepo 저장소 구성(버전 9) 설치 중..." yum -y install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm elif [[ "$os_version" == 10 ]]; then - echo "Elrepo 저장소 구성 (버전 10)을 설치하십시오 ..." + echo "ELRepo 저장소 구성(버전 10) 설치 중..." yum -y install https://www.elrepo.org/elrepo-release-10.el10.elrepo.noarch.rpm else - echo "지원되지 않는 시스템 버전 :$os_version" + echo "지원되지 않는 시스템 버전:$os_version" break_end linux_Settings fi - # Elrepo 커널 저장소를 활성화하고 최신 메인 라인 커널을 설치하십시오. - echo "Elrepo 커널 저장소를 활성화하고 최신 메인 라인 커널을 설치하십시오 ..." + # ELRepo 커널 저장소를 활성화하고 최신 메인라인 커널을 설치합니다. + echo "ELRepo 커널 저장소를 활성화하고 최신 메인라인 커널을 설치하세요..." # yum -y --enablerepo=elrepo-kernel install kernel-ml yum --nogpgcheck -y --enablerepo=elrepo-kernel install kernel-ml - echo "Elrepo 저장소 구성이 설치되어 최신 메인 라인 커널로 업데이트됩니다." + echo "ELRepo 저장소 구성을 설치하고 최신 메인라인 커널로 업데이트했습니다." server_reboot } @@ -4971,37 +5415,37 @@ elrepo_install() { elrepo() { root_use - send_stats "레드 모자 커널 관리" + send_stats "Red Hat 커널 관리" if uname -r | grep -q 'elrepo'; then while true; do clear kernel_version=$(uname -r) - echo "Elrepo 커널을 설치했습니다" - echo "현재 커널 버전 :$kernel_version" + echo "elrepo 커널을 설치했습니다" + echo "현재 커널 버전:$kernel_version" echo "" echo "커널 관리" echo "------------------------" - echo "1. Elrepo 커널 업데이트 2. Elrepo 커널 제거" + echo "1. elrepo 커널 업데이트 2. elrepo 커널 제거" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps elrepo_install - send_stats "Red Hat 커널을 업데이트하십시오" + send_stats "Red Hat 커널 업데이트" server_reboot ;; 2) dnf remove -y elrepo-release rpm -qa | grep elrepo | grep kernel | xargs rpm -e --nodeps - echo "Elrepo 커널은 제거되었습니다. 다시 시작한 후에도 적용됩니다" - send_stats "빨간 모자 커널을 제거하십시오" + echo "elrepo 커널이 제거되었습니다. 재시작 후 적용" + send_stats "Red Hat 커널 제거" server_reboot ;; @@ -5014,26 +5458,26 @@ elrepo() { else clear - echo "데이터를 백업하고 Linux 커널을 업그레이드합니다." - echo "비디오 소개 : https://www.bilibili.com/video/bv1mh4y1w7qa?t=529.2" + echo "데이터를 백업해 주시면 Linux 커널을 업그레이드해 드리겠습니다." + echo "영상 소개: https://www.bilibili.com/video/BV1mH4y1w7qA?t=529.2" echo "------------------------------------------------" - echo "Red Hat 시리즈 배포 Centos/Redhat/Alma/Rocky/Oracle 만 지원합니다" - echo "Linux 커널을 업그레이드하면 시스템 성능 및 보안이 향상 될 수 있습니다. 조건이 허용되고 생산 환경을 조심스럽게 업그레이드하는 경우 시도하는 것이 좋습니다!" + echo "Red Hat 시리즈 배포판 CentOS/RedHat/Alma/Rocky/oracle만 지원" + echo "Linux 커널을 업그레이드하면 시스템 성능과 보안이 향상될 수 있습니다. 가능하다면 시도해 보시고, 프로덕션 환경을 주의해서 업그레이드하시는 것을 추천드립니다!" echo "------------------------------------------------" - read -e -p "계속할거야? (Y/N) :" choice + read -e -p "계속하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) check_swap elrepo_install - send_stats "Red Hat 커널을 업그레이드하십시오" + send_stats "Red Hat 커널 업그레이드" server_reboot ;; [Nn]) echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac fi @@ -5044,7 +5488,7 @@ elrepo() { clamav_freshclam() { - echo -e "${gl_huang}바이러스 데이터베이스 업데이트 ...${gl_bai}" + echo -e "${gl_huang}바이러스 데이터베이스 업데이트 중...${gl_bai}" docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ @@ -5054,19 +5498,19 @@ clamav_freshclam() { clamav_scan() { if [ $# -eq 0 ]; then - echo "스캔 할 디렉토리를 지정하십시오." + echo "스캔할 디렉터리를 지정하세요." return fi - echo -e "${gl_huang}스캔 디렉토리 $@...${gl_bai}" + echo -e "${gl_huang}$@ 디렉터리를 검색하는 중...${gl_bai}" - # 마운트 매개 변수를 빌드하십시오 + # 마운트 매개변수 빌드 local MOUNT_PARAMS="" for dir in "$@"; do MOUNT_PARAMS+="--mount type=bind,source=${dir},target=/mnt/host${dir} " done - # Clamscan 명령 매개 변수를 작성하십시오 + # clamscan 명령 매개변수 빌드 local SCAN_PARAMS="" for dir in "$@"; do SCAN_PARAMS+="/mnt/host${dir} " @@ -5075,8 +5519,8 @@ clamav_scan() { mkdir -p /home/docker/clamav/log/ > /dev/null 2>&1 > /home/docker/clamav/log/scan.log > /dev/null 2>&1 - # Docker 명령을 실행하십시오 - docker run -it --rm \ + # 도커 명령 실행 + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5084,8 +5528,8 @@ clamav_scan() { clamav/clamav-debian:latest \ clamscan -r --log=/var/log/clamav/scan.log $SCAN_PARAMS - echo -e "${gl_lv}$@ scan이 완료되고 바이러스 보고서가 저장됩니다${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" - echo -e "${gl_lv}바이러스가 있다면 제발${gl_huang}scan.log${gl_lv}파일에서 찾은 키워드를 검색하여 바이러스의 위치를 확인하십시오.${gl_bai}" + echo -e "${gl_lv}$@ 扫描完成,病毒报告存放在${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" + echo -e "${gl_lv}바이러스 있으면 제발${gl_huang}scan.log${gl_lv}파일에서 FOUND 키워드를 검색하여 바이러스 위치를 확인하세요.${gl_bai}" } @@ -5097,23 +5541,23 @@ clamav_scan() { clamav() { root_use - send_stats "바이러스 스캔 관리" + send_stats "바이러스 검사 관리" while true; do clear - echo "Clamav 바이러스 스캐닝 도구" - echo "비디오 소개 : https://www.bilibili.com/video/bv1tqvze4eqm?t=0.1" + echo "clamav 바이러스 검사 도구" + echo "영상 소개: https://www.bilibili.com/video/BV1TqvZe4EQm?t=0.1" echo "------------------------" - echo "오픈 소스 바이러스 백신 소프트웨어 도구로 주로 다양한 유형의 맬웨어를 감지하고 제거하는 데 사용됩니다." - echo "바이러스, 트로이 목마, 스파이웨어, 악성 스크립트 및 기타 유해한 소프트웨어를 포함합니다." + echo "다양한 유형의 악성 코드를 탐지하고 제거하는 데 주로 사용되는 오픈 소스 바이러스 백신 소프트웨어 도구입니다." + echo "바이러스, 트로이 목마, 스파이웨어, 악성 스크립트 및 기타 유해한 소프트웨어가 포함됩니다." echo "------------------------" - echo -e "${gl_lv}1. 전체 디스크 스캔${gl_bai} ${gl_huang}2. 중요한 디렉토리를 스캔하십시오${gl_bai} ${gl_kjlan}3. 사용자 정의 디렉토리 스캔${gl_bai}" + echo -e "${gl_lv}1. 전체 스캔${gl_bai} ${gl_huang}2. 중요한 디렉토리 스캔${gl_bai} ${gl_kjlan}3. 사용자 정의 디렉터리 검색${gl_bai}" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "전체 디스크 스캔" + send_stats "전체 스캔" install_docker docker volume create clam_db > /dev/null 2>&1 clamav_freshclam @@ -5131,7 +5575,7 @@ clamav() { ;; 3) send_stats "사용자 정의 디렉토리 스캔" - read -e -p "스캔 할 디렉토리를 입력하십시오." directories + read -e -p "스캔할 디렉터리를 공백으로 구분하여 입력하십시오(예: /etc /var /usr /home /root)." directories install_docker clamav_freshclam clamav_scan $directories @@ -5150,19 +5594,19 @@ clamav() { # 고성능 모드 최적화 기능 optimize_high_performance() { - echo -e "${gl_lv}전환하십시오${tiaoyou_moshi}...${gl_bai}" + echo -e "${gl_lv}로 전환하다${tiaoyou_moshi}...${gl_bai}" - echo -e "${gl_lv}파일 설명자 최적화 ...${gl_bai}" + echo -e "${gl_lv}파일 설명자 최적화...${gl_bai}" ulimit -n 65535 - echo -e "${gl_lv}가상 메모리 최적화 ...${gl_bai}" + echo -e "${gl_lv}가상 메모리 최적화...${gl_bai}" sysctl -w vm.swappiness=10 2>/dev/null sysctl -w vm.dirty_ratio=15 2>/dev/null sysctl -w vm.dirty_background_ratio=5 2>/dev/null sysctl -w vm.overcommit_memory=1 2>/dev/null sysctl -w vm.min_free_kbytes=65536 2>/dev/null - echo -e "${gl_lv}네트워크 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}네트워크 설정 최적화...${gl_bai}" sysctl -w net.core.rmem_max=16777216 2>/dev/null sysctl -w net.core.wmem_max=16777216 2>/dev/null sysctl -w net.core.netdev_max_backlog=250000 2>/dev/null @@ -5174,36 +5618,36 @@ optimize_high_performance() { sysctl -w net.ipv4.tcp_tw_reuse=1 2>/dev/null sysctl -w net.ipv4.ip_local_port_range='1024 65535' 2>/dev/null - echo -e "${gl_lv}캐시 관리 최적화 ...${gl_bai}" + echo -e "${gl_lv}캐시 관리 최적화...${gl_bai}" sysctl -w vm.vfs_cache_pressure=50 2>/dev/null - echo -e "${gl_lv}CPU 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}CPU 설정 최적화...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null - echo -e "${gl_lv}기타 최적화 ...${gl_bai}" - # 대형 투명 페이지를 비활성화하여 대기 시간을 줄입니다 + echo -e "${gl_lv}기타 최적화...${gl_bai}" + # 대기 시간을 줄이기 위해 투명한 대용량 페이지를 비활성화합니다. echo never > /sys/kernel/mm/transparent_hugepage/enabled - # NUMA 밸런싱을 비활성화합니다 + # NUMA 밸런싱 비활성화 sysctl -w kernel.numa_balancing=0 2>/dev/null } -# 이퀄라이제이션 모드 최적화 기능 +# 균형 모드 최적화 기능 optimize_balanced() { - echo -e "${gl_lv}이퀄라이제이션 모드로 전환 ...${gl_bai}" + echo -e "${gl_lv}이퀄라이제이션 모드로 전환...${gl_bai}" - echo -e "${gl_lv}파일 설명자 최적화 ...${gl_bai}" + echo -e "${gl_lv}파일 설명자 최적화...${gl_bai}" ulimit -n 32768 - echo -e "${gl_lv}가상 메모리 최적화 ...${gl_bai}" + echo -e "${gl_lv}가상 메모리 최적화...${gl_bai}" sysctl -w vm.swappiness=30 2>/dev/null sysctl -w vm.dirty_ratio=20 2>/dev/null sysctl -w vm.dirty_background_ratio=10 2>/dev/null sysctl -w vm.overcommit_memory=0 2>/dev/null sysctl -w vm.min_free_kbytes=32768 2>/dev/null - echo -e "${gl_lv}네트워크 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}네트워크 설정 최적화...${gl_bai}" sysctl -w net.core.rmem_max=8388608 2>/dev/null sysctl -w net.core.wmem_max=8388608 2>/dev/null sysctl -w net.core.netdev_max_backlog=125000 2>/dev/null @@ -5215,36 +5659,36 @@ optimize_balanced() { sysctl -w net.ipv4.tcp_tw_reuse=1 2>/dev/null sysctl -w net.ipv4.ip_local_port_range='1024 49151' 2>/dev/null - echo -e "${gl_lv}캐시 관리 최적화 ...${gl_bai}" + echo -e "${gl_lv}캐시 관리 최적화...${gl_bai}" sysctl -w vm.vfs_cache_pressure=75 2>/dev/null - echo -e "${gl_lv}CPU 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}CPU 설정 최적화...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null - echo -e "${gl_lv}기타 최적화 ...${gl_bai}" - # 투명 페이지를 복원하십시오 + echo -e "${gl_lv}기타 최적화...${gl_bai}" + # 투명한 대용량 페이지 복원 echo always > /sys/kernel/mm/transparent_hugepage/enabled - # NUMA 밸런싱을 복원하십시오 + # NUMA 밸런싱 복원 sysctl -w kernel.numa_balancing=1 2>/dev/null } -# 기본 설정 기능을 복원하십시오 +# 기본 설정 복원 기능 restore_defaults() { - echo -e "${gl_lv}기본 설정으로 복원하십시오 ...${gl_bai}" + echo -e "${gl_lv}기본 설정으로 되돌리기...${gl_bai}" - echo -e "${gl_lv}파일 디스크립터 복원 ...${gl_bai}" + echo -e "${gl_lv}파일 설명자를 복원합니다...${gl_bai}" ulimit -n 1024 - echo -e "${gl_lv}가상 메모리 복원 ...${gl_bai}" + echo -e "${gl_lv}가상 메모리 복원...${gl_bai}" sysctl -w vm.swappiness=60 2>/dev/null sysctl -w vm.dirty_ratio=20 2>/dev/null sysctl -w vm.dirty_background_ratio=10 2>/dev/null sysctl -w vm.overcommit_memory=0 2>/dev/null sysctl -w vm.min_free_kbytes=16384 2>/dev/null - echo -e "${gl_lv}네트워크 설정 복원 ...${gl_bai}" + echo -e "${gl_lv}네트워크 설정 재설정...${gl_bai}" sysctl -w net.core.rmem_max=212992 2>/dev/null sysctl -w net.core.wmem_max=212992 2>/dev/null sysctl -w net.core.netdev_max_backlog=1000 2>/dev/null @@ -5256,37 +5700,37 @@ restore_defaults() { sysctl -w net.ipv4.tcp_tw_reuse=0 2>/dev/null sysctl -w net.ipv4.ip_local_port_range='32768 60999' 2>/dev/null - echo -e "${gl_lv}캐시 관리 복원 ...${gl_bai}" + echo -e "${gl_lv}캐시 관리 복원...${gl_bai}" sysctl -w vm.vfs_cache_pressure=100 2>/dev/null - echo -e "${gl_lv}CPU 설정 복원 ...${gl_bai}" + echo -e "${gl_lv}CPU 설정 복원...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=1 2>/dev/null - echo -e "${gl_lv}다른 최적화를 복원 ...${gl_bai}" - # 투명 페이지를 복원하십시오 + echo -e "${gl_lv}다른 최적화 되돌리기...${gl_bai}" + # 투명한 대용량 페이지 복원 echo always > /sys/kernel/mm/transparent_hugepage/enabled - # NUMA 밸런싱을 복원하십시오 + # NUMA 밸런싱 복원 sysctl -w kernel.numa_balancing=1 2>/dev/null } -# 웹 사이트 구축 최적화 기능 +# 웹사이트 구축 최적화 기능 optimize_web_server() { - echo -e "${gl_lv}웹 사이트 구축 최적화 모드로 전환하십시오 ...${gl_bai}" + echo -e "${gl_lv}웹사이트 구축 최적화 모드로 전환...${gl_bai}" - echo -e "${gl_lv}파일 설명자 최적화 ...${gl_bai}" + echo -e "${gl_lv}파일 설명자 최적화...${gl_bai}" ulimit -n 65535 - echo -e "${gl_lv}가상 메모리 최적화 ...${gl_bai}" + echo -e "${gl_lv}가상 메모리 최적화...${gl_bai}" sysctl -w vm.swappiness=10 2>/dev/null sysctl -w vm.dirty_ratio=20 2>/dev/null sysctl -w vm.dirty_background_ratio=10 2>/dev/null sysctl -w vm.overcommit_memory=1 2>/dev/null sysctl -w vm.min_free_kbytes=65536 2>/dev/null - echo -e "${gl_lv}네트워크 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}네트워크 설정 최적화...${gl_bai}" sysctl -w net.core.rmem_max=16777216 2>/dev/null sysctl -w net.core.wmem_max=16777216 2>/dev/null sysctl -w net.core.netdev_max_backlog=5000 2>/dev/null @@ -5298,16 +5742,16 @@ optimize_web_server() { sysctl -w net.ipv4.tcp_tw_reuse=1 2>/dev/null sysctl -w net.ipv4.ip_local_port_range='1024 65535' 2>/dev/null - echo -e "${gl_lv}캐시 관리 최적화 ...${gl_bai}" + echo -e "${gl_lv}캐시 관리 최적화...${gl_bai}" sysctl -w vm.vfs_cache_pressure=50 2>/dev/null - echo -e "${gl_lv}CPU 설정 최적화 ...${gl_bai}" + echo -e "${gl_lv}CPU 설정 최적화...${gl_bai}" sysctl -w kernel.sched_autogroup_enabled=0 2>/dev/null - echo -e "${gl_lv}기타 최적화 ...${gl_bai}" - # 대형 투명 페이지를 비활성화하여 대기 시간을 줄입니다 + echo -e "${gl_lv}기타 최적화...${gl_bai}" + # 대기 시간을 줄이기 위해 투명한 대용량 페이지를 비활성화합니다. echo never > /sys/kernel/mm/transparent_hugepage/enabled - # NUMA 밸런싱을 비활성화합니다 + # NUMA 밸런싱 비활성화 sysctl -w kernel.numa_balancing=0 2>/dev/null @@ -5319,27 +5763,27 @@ Kernel_optimize() { while true; do clear send_stats "Linux 커널 튜닝 관리" - echo "Linux 시스템에서 커널 매개 변수의 최적화" - echo "비디오 소개 : https://www.bilibili.com/video/bv1kb421j7 yg?t=0.1" + echo "Linux 시스템 커널 매개변수 최적화" + echo "영상 소개: https://www.bilibili.com/video/BV1Kb421J7yg?t=0.1" echo "------------------------------------------------" - echo "다양한 시스템 매개 변수 튜닝 모드가 제공되며 사용자는 자체 사용 시나리오에 따라 선택하고 전환 할 수 있습니다." - echo -e "${gl_huang}힌트:${gl_bai}생산 환경에서주의해서 사용하십시오!" + echo "다양한 시스템 매개변수 조정 모드를 제공하며 사용자는 자신의 사용 시나리오에 따라 전환하도록 선택할 수 있습니다." + echo -e "${gl_huang}힌트:${gl_bai}프로덕션 환경에서는 주의해서 사용해주세요!" echo "--------------------" - echo "1. 고성능 최적화 모드 : 시스템 성능을 극대화하고 파일 설명기, 가상 메모리, 네트워크 설정, 캐시 관리 및 CPU 설정을 최적화합니다." - echo "2. 균형 최적화 모드 : 매일 사용하기에 적합한 성능과 자원 소비 사이의 균형." - echo "3. 웹 사이트 최적화 모드 : 웹 사이트 서버에 최적화하여 동시 연결 처리 기능, 응답 속도 및 전반적인 성능을 향상시킵니다." - echo "4. 라이브 브로드 캐스트 최적화 모드 : 라이브 방송 스트리밍의 특별한 요구를 최적화하여 대기 시간을 줄이고 전송 성능을 향상시킵니다." - echo "5. 게임 서버 최적화 모드 : 게임 서버를 위해 동시 처리 기능 및 응답 속도를 향상시킬 최적화." - echo "6. 기본 설정을 복원하십시오. 시스템 설정을 기본 구성으로 복원하십시오." + echo "1. 고성능 최적화 모드: 시스템 성능을 최대화하고 파일 설명자, 가상 메모리, 네트워크 설정, 캐시 관리 및 CPU 설정을 최적화합니다." + echo "2. 균형 잡힌 최적화 모드: 일상적인 사용에 적합한 성능과 리소스 소비 사이의 균형을 유지합니다." + echo "3. 웹사이트 최적화 모드: 웹사이트 서버를 최적화하여 동시 연결 처리 기능, 응답 속도 및 전반적인 성능을 향상시킵니다." + echo "4. 라이브 방송 최적화 모드: 라이브 스트리밍의 특별한 요구 사항을 최적화하여 지연을 줄이고 전송 성능을 향상시킵니다." + echo "5. 게임 서버 최적화 모드: 게임 서버를 최적화하여 동시 처리 기능과 응답 속도를 향상시킵니다." + echo "6. 기본 설정 복원: 시스템 설정을 기본 구성으로 복원합니다." echo "--------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "--------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) cd ~ clear - local tiaoyou_moshi="高性能优化模式" + local tiaoyou_moshi="고성능 최적화 모드" optimize_high_performance send_stats "고성능 모드 최적화" ;; @@ -5353,19 +5797,19 @@ Kernel_optimize() { cd ~ clear optimize_web_server - send_stats "웹 사이트 최적화 모델" + send_stats "웹사이트 최적화 모드" ;; 4) cd ~ clear - local tiaoyou_moshi="直播优化模式" + local tiaoyou_moshi="라이브 방송 최적화 모드" optimize_high_performance send_stats "라이브 스트리밍 최적화" ;; 5) cd ~ clear - local tiaoyou_moshi="游戏服优化模式" + local tiaoyou_moshi="게임 서버 최적화 모드" optimize_high_performance send_stats "게임 서버 최적화" ;; @@ -5373,7 +5817,7 @@ Kernel_optimize() { cd ~ clear restore_defaults - send_stats "기본 설정을 복원하십시오" + send_stats "기본 설정 복원" ;; *) break @@ -5400,7 +5844,7 @@ update_locale() { locale-gen echo "LANG=${lang}" > /etc/default/locale export LANG=${lang} - echo -e "${gl_lv}시스템 언어는 다음으로 수정되었습니다.$langSSH를 다시 연결하면 적용됩니다.${gl_bai}" + echo -e "${gl_lv}시스템 언어가 다음과 같이 수정되었습니다.$lang적용하려면 SSH에 다시 연결하세요.${gl_bai}" hash -r break_end @@ -5409,17 +5853,17 @@ update_locale() { install glibc-langpack-zh localectl set-locale LANG=${lang} echo "LANG=${lang}" | tee /etc/locale.conf - echo -e "${gl_lv}시스템 언어는 다음으로 수정되었습니다.$langSSH를 다시 연결하면 적용됩니다.${gl_bai}" + echo -e "${gl_lv}시스템 언어가 다음과 같이 수정되었습니다.$lang적용하려면 SSH에 다시 연결하세요.${gl_bai}" hash -r break_end ;; *) - echo "지원되지 않는 시스템 :$ID" + echo "지원되지 않는 시스템:$ID" break_end ;; esac else - echo "지원되지 않는 시스템, 시스템 유형을 인식 할 수 없습니다." + echo "지원되지 않는 시스템, 시스템 유형을 식별할 수 없습니다." break_end fi } @@ -5429,29 +5873,29 @@ update_locale() { linux_language() { root_use -send_stats "스위치 시스템 언어" +send_stats "시스템 언어 전환" while true; do clear - echo "현재 시스템 언어 :$LANG" + echo "현재 시스템 언어:$LANG" echo "------------------------" - echo "1. 영어 2. 중국어 3. 전통 중국어" + echo "1. 영어 2. 중국어 간체 3. 중국어 번체" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) update_locale "en_US.UTF-8" "en_US.UTF-8" - send_stats "영어로 전환하십시오" + send_stats "영어로 전환" ;; 2) update_locale "zh_CN.UTF-8" "zh_CN.UTF-8" - send_stats "단순화 된 중국어로 전환하십시오" + send_stats "중국어 간체로 전환" ;; 3) update_locale "zh_TW.UTF-8" "zh_TW.UTF-8" - send_stats "전통적인 중국어로 전환하십시오" + send_stats "중국어 번체로 전환" ;; *) break @@ -5473,7 +5917,7 @@ else echo "${bianse}" >> ~/.profile # source ~/.profile fi -echo -e "${gl_lv}변경이 완료되었습니다. 변경 사항을 볼 수 있도록 SSH를 다시 연결하십시오!${gl_bai}" +echo -e "${gl_lv}변경이 완료되었습니다. 변경 사항을 보려면 SSH에 다시 연결하세요!${gl_bai}" hash -r break_end @@ -5484,10 +5928,10 @@ break_end shell_bianse() { root_use - send_stats "명령 라인 미화 도구" + send_stats "명령줄 미화 도구" while true; do clear - echo "명령 라인 미화 도구" + echo "명령줄 미화 도구" echo "------------------------" echo -e "1. \033[1;32mroot \033[1;34mlocalhost \033[1;31m~ \033[0m${gl_bai}#" echo -e "2. \033[1;35mroot \033[1;36mlocalhost \033[1;33m~ \033[0m${gl_bai}#" @@ -5497,9 +5941,9 @@ shell_bianse() { echo -e "6. \033[1;33mroot \033[1;34mlocalhost \033[1;35m~ \033[0m${gl_bai}#" echo -e "7. root localhost ~ #" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) @@ -5544,7 +5988,7 @@ shell_bianse() { linux_trash() { root_use - send_stats "시스템 재활용 스테이션" + send_stats "시스템 휴지통" local bashrc_profile="/root/.bashrc" local TRASH_DIR="$HOME/.local/share/Trash/files" @@ -5553,23 +5997,23 @@ linux_trash() { local trash_status if ! grep -q "trash-put" "$bashrc_profile"; then - trash_status="${gl_hui}未启用${gl_bai}" + trash_status="${gl_hui}활성화되지 않음${gl_bai}" else - trash_status="${gl_lv}已启用${gl_bai}" + trash_status="${gl_lv}활성화됨${gl_bai}" fi clear - echo -e "현재 재활용 쓰레기통${trash_status}" - echo -e "활성화 후 RM이 삭제 한 파일은 먼저 재활용 빈에 입력하여 중요한 파일의 잘못된 삭제를 방지합니다!" + echo -e "현재 휴지통${trash_status}" + echo -e "활성화한 후에는 중요한 파일이 실수로 삭제되는 것을 방지하기 위해 rm으로 삭제된 파일이 먼저 휴지통에 저장됩니다!" echo "------------------------------------------------" - ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "재활용 쓰레기통은 비어 있습니다" + ls -l --color=auto "$TRASH_DIR" 2>/dev/null || echo "휴지통이 비어 있습니다." echo "------------------------" - echo "1. 재활용 빈을 활성화합니다. 2. 재활용 쓰레기통을 닫습니다." - echo "3. 컨텐츠를 복원 4. 재활용 쓰레기통을 지 웁니다" + echo "1. 휴지통 활성화 2. 휴지통 닫기" + echo "3. 콘텐츠 복원 4. 휴지통 비우기" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) @@ -5577,7 +6021,7 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='trash-put'" >> "$bashrc_profile" source "$bashrc_profile" - echo "Recycle Bin이 활성화되고 삭제 된 파일이 Recycle Bin으로 이동됩니다." + echo "휴지통이 활성화되면 삭제된 파일은 휴지통으로 이동됩니다." sleep 2 ;; 2) @@ -5585,11 +6029,11 @@ linux_trash() { sed -i '/alias rm/d' "$bashrc_profile" echo "alias rm='rm -i'" >> "$bashrc_profile" source "$bashrc_profile" - echo "재활용 빈이 닫히고 파일이 직접 삭제됩니다." + echo "휴지통이 닫히고 파일이 직접 삭제됩니다." sleep 2 ;; 3) - read -e -p "복원 할 파일 이름을 입력하십시오." file_to_restore + read -e -p "복원할 파일 이름을 입력하세요:" file_to_restore if [ -e "$TRASH_DIR/$file_to_restore" ]; then mv "$TRASH_DIR/$file_to_restore" "$HOME/" echo "$file_to_restore홈 디렉토리로 복원되었습니다." @@ -5598,10 +6042,10 @@ linux_trash() { fi ;; 4) - read -e -p "재활용 쓰레기통을 지우셨습니까? [Y/N] :" confirm + read -e -p "휴지통을 비우시겠습니까? [예/아니요]:" confirm if [[ "$confirm" == "y" ]]; then trash-empty - echo "재활용 쓰레기통이 지워졌습니다." + echo "휴지통이 비워졌습니다." fi ;; *) @@ -5611,21 +6055,24 @@ linux_trash() { done } +linux_fav() { +send_stats "명령 즐겨찾기" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} - -# 백업을 만듭니다 +# 백업 만들기 create_backup() { - send_stats "백업을 만듭니다" + send_stats "백업 만들기" local TIMESTAMP=$(date +"%Y%m%d%H%M%S") - # 사용자에게 백업 디렉토리를 입력하라는 메시지를 표시하십시오 - echo "백업 예제 :" - echo "- 단일 디렉토리를 백업 : /var /www" - echo "- 여러 디렉토리 백업 : /etc /home /var /log" - echo "- Direct Enter는 기본 디렉토리 ( /etc /usr /home)를 사용합니다." - read -r -p "백업 디렉토리를 입력하십시오 (여러 디렉토리가 공간별로 구분되며 직접 입력하면 기본 디렉토리를 사용하십시오)." input + # 사용자에게 백업 디렉터리를 묻는 메시지 표시 + echo "백업 생성 예:" + echo "- 단일 디렉터리 백업: /var/www" + echo "- 여러 디렉터리 백업: /etc /home /var/log" + echo "- Enter를 눌러 기본 디렉터리(/etc/usr/home)를 사용합니다." + read -r -p "백업할 디렉터리를 입력하십시오(여러 디렉터리를 공백으로 구분하고 Enter를 눌러 기본 디렉터리를 사용하십시오)." input - # 사용자가 디렉토리를 입력하지 않으면 기본 디렉토리를 사용하십시오. + # 사용자가 디렉터리를 입력하지 않으면 기본 디렉터리가 사용됩니다. if [ -z "$input" ]; then BACKUP_PATHS=( "/etc" # 配置文件和软件包配置 @@ -5633,92 +6080,92 @@ create_backup() { "/home" # 用户数据 ) else - # 사용자가 입력 한 디렉토리를 공백 별 배열로 분리합니다. + # 사용자가 입력한 디렉토리를 공백으로 배열로 구분합니다. IFS=' ' read -r -a BACKUP_PATHS <<< "$input" fi - # 백업 파일 접두사를 생성합니다 + # 백업 파일 접두사 생성 local PREFIX="" for path in "${BACKUP_PATHS[@]}"; do - # 디렉토리 이름을 추출하고 슬래시를 제거하십시오 + # 디렉토리 이름 추출 및 슬래시 제거 dir_name=$(basename "$path") PREFIX+="${dir_name}_" done - # 마지막 밑줄을 제거하십시오 + # 마지막 밑줄 제거 local PREFIX=${PREFIX%_} - # 백업 파일 이름을 생성합니다 + # 백업 파일 이름 생성 local BACKUP_NAME="${PREFIX}_$TIMESTAMP.tar.gz" - # 사용자가 선택한 디렉토리를 인쇄하십시오 - echo "선택한 백업 디렉토리는 다음과 같습니다." + # 사용자가 선택한 디렉토리 인쇄 + echo "선택한 백업 디렉터리는 다음과 같습니다." for path in "${BACKUP_PATHS[@]}"; do echo "- $path" done - # 백업을 만듭니다 + # 백업 만들기 echo "백업 생성$BACKUP_NAME..." install tar tar -czvf "$BACKUP_DIR/$BACKUP_NAME" "${BACKUP_PATHS[@]}" - # 명령이 성공했는지 확인하십시오 + # 명령이 성공했는지 확인 if [ $? -eq 0 ]; then - echo "백업은 성공적으로 생성되었습니다.$BACKUP_DIR/$BACKUP_NAME" + echo "백업이 성공적으로 생성되었습니다:$BACKUP_DIR/$BACKUP_NAME" else - echo "백업 생성이 실패했습니다!" + echo "백업 생성에 실패했습니다!" exit 1 fi } -# 백업을 복원하십시오 +# 백업 복원 restore_backup() { - send_stats "백업을 복원하십시오" - # 복원하려는 백업을 선택하십시오 - read -e -p "복원하려면 백업 파일 이름을 입력하십시오." BACKUP_NAME + send_stats "백업 복원" + # 복원할 백업을 선택하세요 + read -e -p "복원할 백업 파일 이름을 입력하십시오:" BACKUP_NAME - # 백업 파일이 있는지 확인하십시오 + # 백업 파일이 있는지 확인 if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then echo "백업 파일이 존재하지 않습니다!" exit 1 fi - echo "백업 복구$BACKUP_NAME..." + echo "백업 복원 중$BACKUP_NAME..." tar -xzvf "$BACKUP_DIR/$BACKUP_NAME" -C / if [ $? -eq 0 ]; then - echo "백업 및 복원을 성공적으로 복원하십시오!" + echo "백업 및 복원 성공!" else - echo "백업 복구 실패!" + echo "백업 복원에 실패했습니다!" exit 1 fi } -# 백업을 나열합니다 +# 백업 나열 list_backups() { - echo "사용 가능한 백업 :" + echo "사용 가능한 백업:" ls -1 "$BACKUP_DIR" } -# 백업을 삭제하십시오 +# 백업 삭제 delete_backup() { - send_stats "백업을 삭제하십시오" + send_stats "백업 삭제" - read -e -p "삭제하려면 백업 파일 이름을 입력하십시오." BACKUP_NAME + read -e -p "삭제할 백업 파일 이름을 입력하십시오:" BACKUP_NAME - # 백업 파일이 있는지 확인하십시오 + # 백업 파일이 있는지 확인 if [ ! -f "$BACKUP_DIR/$BACKUP_NAME" ]; then echo "백업 파일이 존재하지 않습니다!" exit 1 fi - # 백업을 삭제하십시오 + # 백업 삭제 rm -f "$BACKUP_DIR/$BACKUP_NAME" if [ $? -eq 0 ]; then - echo "백업이 성공적으로 삭제되었습니다!" + echo "백업이 삭제되었습니다!" else - echo "백업 삭제가 실패했습니다!" + echo "백업 삭제에 실패했습니다!" exit 1 fi } @@ -5734,18 +6181,18 @@ linux_backup() { echo "------------------------" list_backups echo "------------------------" - echo "1. 백업 만들기 2. 백업 복원 3. 백업 삭제" + echo "1. 백업 생성 2. 백업 복원 3. 백업 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) create_backup ;; 2) restore_backup ;; 3) delete_backup ;; *) break ;; esac - read -e -p "계속하려면 Enter를 누르십시오 ..." + read -e -p "계속하려면 Enter를 누르세요..." done } @@ -5759,54 +6206,54 @@ linux_backup() { # 연결 목록 표시 list_connections() { - echo "저장된 연결 :" + echo "저장된 연결:" echo "------------------------" cat "$CONFIG_FILE" | awk -F'|' '{print NR " - " $1 " (" $2 ")"}' echo "------------------------" } -# 새 연결을 추가하십시오 +# 새 연결 추가 add_connection() { - send_stats "새 연결을 추가하십시오" - echo "새 연결을 만드는 예 :" - echo "- 연결 이름 : my_server" - echo "-IP 주소 : 192.168.1.100" - echo "- 사용자 이름 : 루트" - echo "- 포트 : 22" + send_stats "새 연결 추가" + echo "새 연결 생성의 예:" + echo "- 연결 이름: my_server" + echo "- IP 주소: 192.168.1.100" + echo "- 사용자 이름: 루트" + echo "- 포트: 22" echo "------------------------" - read -e -p "연결 이름을 입력하십시오 :" name - read -e -p "IP 주소를 입력하십시오 :" ip - read -e -p "사용자 이름 (기본값 : 루트)을 입력하십시오 :" user + read -e -p "연결 이름을 입력하세요:" name + read -e -p "IP 주소를 입력하세요:" ip + read -e -p "사용자 이름을 입력하십시오(기본값: 루트):" user local user=${user:-root} # 如果用户未输入,则使用默认值 root - read -e -p "포트 번호를 입력하십시오 (기본값 : 22) :" port + read -e -p "포트 번호를 입력하십시오(기본값: 22):" port local port=${port:-22} # 如果用户未输入,则使用默认值 22 - echo "인증 방법을 선택하십시오 :" + echo "인증 방법을 선택하세요:" echo "1. 비밀번호" - echo "2. 키" - read -e -p "선택 (1/2)을 입력하십시오 :" auth_choice + echo "2. 열쇠" + read -e -p "원하는 항목(1/2)을 입력하세요." auth_choice case $auth_choice in 1) - read -s -p "비밀번호를 입력하십시오 :" password_or_key + read -s -p "비밀번호를 입력하세요:" password_or_key echo # 换行 ;; 2) - echo "키 내용을 붙여 넣으십시오 (붙여 넣기 후 Enter Enter를 두 번 누릅니다) :" + echo "주요 내용을 붙여넣으세요(붙인 후 Enter를 두 번 누르세요)." local password_or_key="" while IFS= read -r line; do - # 입력이 비어 있고 키 컨텐츠에 이미 시작이 포함되어 있으면 입력이 끝납니다. + # 입력이 빈 줄이고 키 내용에 이미 시작 부분이 포함된 경우 입력을 종료합니다. if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # 첫 번째 줄이거나 키 컨텐츠가 입력 된 경우 계속 추가하십시오. + # 첫 번째 줄이거나 이미 핵심 내용 입력을 시작했다면 계속해서 추가하세요. if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then local password_or_key+="${line}"$'\n' fi done - # 주요 내용인지 확인하십시오 + # 핵심 내용인지 확인해보세요 if [[ "$password_or_key" == *"-----BEGIN"* && "$password_or_key" == *"PRIVATE KEY-----"* ]]; then local key_file="$KEY_DIR/$name.key" echo -n "$password_or_key" > "$key_file" @@ -5815,31 +6262,31 @@ add_connection() { fi ;; *) - echo "잘못된 선택!" + echo "잘못된 선택입니다!" return ;; esac echo "$name|$ip|$user|$port|$password_or_key" >> "$CONFIG_FILE" - echo "연결이 저장됩니다!" + echo "연결이 저장되었습니다!" } -# 연결을 삭제하십시오 +# 연결 삭제 delete_connection() { - send_stats "연결을 삭제하십시오" - read -e -p "삭제하려면 연결 번호를 입력하십시오." num + send_stats "연결 삭제" + read -e -p "삭제할 연결 번호를 입력하세요:" num local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "오류 : 해당 연결을 찾을 수 없었습니다." + echo "오류: 해당 연결을 찾을 수 없습니다." return fi IFS='|' read -r name ip user port password_or_key <<< "$connection" - # 연결이 키 파일을 사용하는 경우 키 파일을 삭제하십시오. + # 연결이 키 파일을 사용하는 경우 키 파일을 삭제하세요. if [[ "$password_or_key" == "$KEY_DIR"* ]]; then rm -f "$password_or_key" fi @@ -5848,44 +6295,44 @@ delete_connection() { echo "연결이 삭제되었습니다!" } -# 연결을 사용하십시오 +# 연결 사용 use_connection() { - send_stats "연결을 사용하십시오" - read -e -p "사용할 연결 번호를 입력하십시오." num + send_stats "연결 사용" + read -e -p "사용할 연결 번호를 입력하세요:" num local connection=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$connection" ]]; then - echo "오류 : 해당 연결을 찾을 수 없었습니다." + echo "오류: 해당 연결을 찾을 수 없습니다." return fi IFS='|' read -r name ip user port password_or_key <<< "$connection" - echo "연결$name ($ip)..." + echo "연결 중$name ($ip)..." if [[ -f "$password_or_key" ]]; then - # 키와 연결하십시오 + # 키를 사용하여 연결 ssh -o StrictHostKeyChecking=no -i "$password_or_key" -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then - echo "연결 실패! 다음을 확인하십시오." - echo "1. 키 파일 경로가 정확합니까?$password_or_key" - echo "2. 키 파일 권한이 올바른지 여부 (600이어야 함)." - echo "3. 대상 서버가 키를 사용하여 로그인 할 수 있는지 여부." + echo "연결에 실패했습니다! 다음 사항을 확인하세요." + echo "1. 키파일 경로가 맞나요?$password_or_key" + echo "2. 키 파일 권한이 올바른가요(600이어야 함)." + echo "3. 대상 서버에서 키를 이용한 로그인을 허용하는지 여부." fi else - # 비밀번호로 연결하십시오 + # 비밀번호를 사용하여 연결 if ! command -v sshpass &> /dev/null; then - echo "오류 : Sshpass가 설치되지 않았습니다. 먼저 Sshpass를 설치하십시오." - echo "설치 방법 :" + echo "오류: sshpass가 설치되지 않았습니다. 먼저 sshpass를 설치하십시오." + echo "설치 방법:" echo " - Ubuntu/Debian: apt install sshpass" echo " - CentOS/RHEL: yum install sshpass" return fi sshpass -p "$password_or_key" ssh -o StrictHostKeyChecking=no -p "$port" "$user@$ip" if [[ $? -ne 0 ]]; then - echo "연결 실패! 다음을 확인하십시오." - echo "1. 사용자 이름과 비밀번호가 올바른지 여부." - echo "2. 대상 서버가 암호 로그인을 허용하는지 여부." - echo "3. 대상 서버의 SSH 서비스가 정상적으로 실행되는지 여부." + echo "연결에 실패했습니다! 다음 사항을 확인하세요." + echo "1. 사용자 이름과 비밀번호가 정확합니까?" + echo "2. 대상 서버에서 비밀번호 로그인을 허용하는지 여부." + echo "3. 대상 서버의 SSH 서비스가 정상적으로 실행되고 있는지 여부." fi fi } @@ -5897,7 +6344,7 @@ ssh_manager() { CONFIG_FILE="$HOME/.ssh_connections" KEY_DIR="$HOME/.ssh/ssh_manager_keys" - # 구성 파일과 키 디렉토리가 존재하는지 확인하고 존재하지 않으면 작성하십시오. + # 구성 파일과 키 디렉터리가 있는지 확인하고 없으면 만듭니다. if [[ ! -f "$CONFIG_FILE" ]]; then touch "$CONFIG_FILE" fi @@ -5910,20 +6357,20 @@ ssh_manager() { while true; do clear echo "SSH 원격 연결 도구" - echo "SSH를 통해 다른 Linux 시스템에 연결할 수 있습니다" + echo "SSH를 통해 다른 Linux 시스템에 연결할 수 있습니다." echo "------------------------" list_connections - echo "1. 새 연결 만들기 2. 연결 사용 3. 연결 삭제" + echo "1. 새 연결 생성 2. 연결 사용 3. 연결 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) add_connection ;; 2) use_connection ;; 3) delete_connection ;; 0) break ;; - *) echo "잘못된 선택, 다시 시도하십시오." ;; + *) echo "선택이 잘못되었습니다. 다시 시도해 주세요." ;; esac done } @@ -5939,156 +6386,156 @@ ssh_manager() { -# 사용 가능한 하드 디스크 파티션을 나열하십시오 +# 사용 가능한 하드 디스크 파티션 나열 list_partitions() { - echo "사용 가능한 하드 디스크 파티션 :" + echo "사용 가능한 하드 드라이브 파티션:" lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT | grep -v "sr\|loop" } -# 파티션을 장착하십시오 +# 마운트 파티션 mount_partition() { - send_stats "파티션을 장착하십시오" - read -e -p "장착 할 파티션 이름을 입력하십시오 (예 : SDA1) :" PARTITION + send_stats "마운트 파티션" + read -e -p "마운트할 파티션의 이름을 입력하십시오(예: sda1):" PARTITION - # 파티션이 있는지 확인하십시오 + # 파티션이 존재하는지 확인 if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then echo "파티션이 존재하지 않습니다!" return fi - # 파티션이 이미 장착되어 있는지 확인하십시오 + # 파티션이 마운트되었는지 확인 if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "파티션은 이미 장착되어 있습니다!" + echo "파티션이 마운트되었습니다!" return fi - # 마운트 포인트를 만듭니다 + # 마운트 지점 생성 MOUNT_POINT="/mnt/$PARTITION" mkdir -p "$MOUNT_POINT" - # 파티션을 장착하십시오 + # 마운트 파티션 mount "/dev/$PARTITION" "$MOUNT_POINT" if [ $? -eq 0 ]; then - echo "파티션 마운트 성공적으로 :$MOUNT_POINT" + echo "파티션이 성공적으로 마운트되었습니다:$MOUNT_POINT" else - echo "파티션 마운트 실패!" + echo "파티션 마운트에 실패했습니다!" rmdir "$MOUNT_POINT" fi } -# 파티션을 제거하십시오 +# 파티션 마운트 해제 unmount_partition() { - send_stats "파티션을 제거하십시오" - read -e -p "파티션 이름 (예 : SDA1)을 입력하십시오." PARTITION + send_stats "파티션 마운트 해제" + read -e -p "마운트 해제할 파티션의 이름을 입력하십시오(예: sda1):" PARTITION - # 파티션이 이미 장착되어 있는지 확인하십시오 + # 파티션이 마운트되었는지 확인 MOUNT_POINT=$(lsblk -o MOUNTPOINT | grep -w "$PARTITION") if [ -z "$MOUNT_POINT" ]; then - echo "파티션이 장착되지 않았습니다!" + echo "파티션이 마운트되지 않았습니다!" return fi - # 파티션을 제거하십시오 + # 파티션 마운트 해제 umount "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "파티션 분할 해제 성공 :$MOUNT_POINT" + echo "파티션이 성공적으로 제거되었습니다:$MOUNT_POINT" rmdir "$MOUNT_POINT" else - echo "파티션 제거 실패!" + echo "파티션 제거에 실패했습니다!" fi } -# 목록 장착 파티션 +# 마운트된 파티션 나열 list_mounted_partitions() { - echo "마운트 파티션 :" + echo "마운트된 파티션:" df -h | grep -v "tmpfs\|udev\|overlay" } -# 형식 파티션 +# 파티션 포맷 format_partition() { - send_stats "형식 파티션" - read -e -p "파티션 이름을 형식 (예 : SDA1)에 입력하십시오." PARTITION + send_stats "파티션 포맷" + read -e -p "포맷할 파티션의 이름을 입력하십시오(예: sda1):" PARTITION - # 파티션이 있는지 확인하십시오 + # 파티션이 존재하는지 확인 if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then echo "파티션이 존재하지 않습니다!" return fi - # 파티션이 이미 장착되어 있는지 확인하십시오 + # 파티션이 마운트되었는지 확인 if lsblk -o MOUNTPOINT | grep -w "$PARTITION" > /dev/null; then - echo "파티션이 장착되었습니다. 먼저 제거하십시오!" + echo "파티션이 마운트되었습니다. 먼저 마운트를 해제하세요!" return fi - # 파일 시스템 유형을 선택하십시오 - echo "파일 시스템 유형을 선택하십시오 :" + # 파일 시스템 유형 선택 + echo "파일 시스템 유형을 선택하십시오:" echo "1. ext4" echo "2. xfs" echo "3. ntfs" echo "4. vfat" - read -e -p "선택을 입력하십시오 :" FS_CHOICE + read -e -p "선택사항을 입력하세요:" FS_CHOICE case $FS_CHOICE in 1) FS_TYPE="ext4" ;; 2) FS_TYPE="xfs" ;; 3) FS_TYPE="ntfs" ;; 4) FS_TYPE="vfat" ;; - *) echo "잘못된 선택!"; return ;; + *) echo "잘못된 선택입니다!"; return ;; esac - # 형식을 확인하십시오 - read -e -p "파티션 형식 확인 /dev /$PARTITION~을 위한$FS_TYPE그게? (Y/N) :" CONFIRM + # 포맷 확인 + read -e -p "포맷된 파티션 /dev/ 확인$PARTITION~을 위한$FS_TYPE? (예/아니요):" CONFIRM if [ "$CONFIRM" != "y" ]; then echo "작업이 취소되었습니다." return fi - # 형식 파티션 - echo "파티션 서식 /dev /$PARTITION~을 위한$FS_TYPE ..." + # 파티션 포맷 + echo "파티션 /dev/ 포맷 중$PARTITION~을 위한$FS_TYPE ..." mkfs.$FS_TYPE "/dev/$PARTITION" if [ $? -eq 0 ]; then - echo "파티션 형식이 성공적이었습니다!" + echo "파티션이 성공적으로 포맷되었습니다!" else - echo "파티션 형식이 실패했습니다!" + echo "파티션 포맷에 실패했습니다!" fi } -# 파티션 상태를 확인하십시오 +# 파티션 상태 확인 check_partition() { - send_stats "파티션 상태를 확인하십시오" - read -e -p "파티션 이름을 입력하여 확인하십시오 (예 : SDA1) :" PARTITION + send_stats "파티션 상태 확인" + read -e -p "확인할 파티션 이름을 입력하세요(예: sda1):" PARTITION - # 파티션이 있는지 확인하십시오 + # 파티션이 존재하는지 확인 if ! lsblk -o NAME | grep -w "$PARTITION" > /dev/null; then echo "파티션이 존재하지 않습니다!" return fi - # 파티션 상태를 확인하십시오 - echo "파티션 /개발자 /$PARTITION상태:" + # 파티션 상태 확인 + echo "파티션 확인 /dev/$PARTITION상태:" fsck "/dev/$PARTITION" } # 메인 메뉴 disk_manager() { - send_stats "하드 디스크 관리 기능" + send_stats "하드디스크 관리 기능" while true; do clear - echo "하드 디스크 파티션 관리" - echo -e "${gl_huang}이 기능은 테스트 기간 동안 내부적으로 테스트되므로 생산 환경에서 사용하지 마십시오.${gl_bai}" + echo "하드 드라이브 파티션 관리" + echo -e "${gl_huang}이 기능은 내부 테스트 중이므로 프로덕션 환경에서는 사용하면 안 됩니다.${gl_bai}" echo "------------------------" list_partitions echo "------------------------" - echo "1. 파티션 마운트 2. 파티션 3. 마운트 파티션보기" - echo "4. 파티션 형식 5. 파티션 상태를 확인하십시오" + echo "1. 파티션 마운트 2. 파티션 마운트 해제 3. 마운트된 파티션 보기" + echo "4. 파티션 포맷 5. 파티션 상태 확인" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) mount_partition ;; 2) unmount_partition ;; @@ -6097,7 +6544,7 @@ disk_manager() { 5) check_partition ;; *) break ;; esac - read -e -p "계속하려면 Enter를 누르십시오 ..." + read -e -p "계속하려면 Enter를 누르세요..." done } @@ -6106,55 +6553,55 @@ disk_manager() { # 작업 목록 표시 list_tasks() { - echo "저장된 동기화 작업 :" + echo "저장된 동기화 작업:" echo "---------------------------------" awk -F'|' '{print NR " - " $1 " ( " $2 " -> " $3":"$4 " )"}' "$CONFIG_FILE" echo "---------------------------------" } -# 새로운 작업을 추가하십시오 +# 새 작업 추가 add_task() { - send_stats "새 동기화 작업을 추가하십시오" - echo "새 동기화 작업 작성 예 :" - echo "- 작업 이름 : Backup_www" - echo "- 로컬 디렉토리 : /var /www" - echo "- 원격 주소 : user@192.168.1.100" - echo "- 원격 디렉토리 : /백업 /www" - echo "- 포트 번호 (기본 22)" + send_stats "새 동기화 작업 추가" + echo "새 동기화 작업 생성의 예:" + echo "- 작업 이름: backup_www" + echo "- 로컬 디렉터리: /var/www" + echo "- 원격 주소: user@192.168.1.100" + echo "- 원격 디렉터리: /backup/www" + echo "- 포트 번호(기본값 22)" echo "---------------------------------" - read -e -p "작업 이름을 입력하십시오 :" name - read -e -p "로컬 디렉토리를 입력하십시오 :" local_path - read -e -p "원격 디렉토리를 입력하십시오 :" remote_path - read -e -p "원격 사용자 @IP를 입력하십시오 :" remote - read -e -p "SSH 포트 (기본값 22)를 입력하십시오 :" port + read -e -p "작업 이름을 입력하세요:" name + read -e -p "로컬 디렉토리를 입력하십시오:" local_path + read -e -p "원격 디렉토리를 입력하십시오:" remote_path + read -e -p "원격 user@IP를 입력하십시오:" remote + read -e -p "SSH 포트(기본값 22)를 입력하세요." port port=${port:-22} - echo "인증 방법을 선택하십시오 :" + echo "인증 방법을 선택하세요:" echo "1. 비밀번호" - echo "2. 키" - read -e -p "선택하십시오 (1/2) :" auth_choice + echo "2. 열쇠" + read -e -p "(1/2)을 선택하세요:" auth_choice case $auth_choice in 1) - read -s -p "비밀번호를 입력하십시오 :" password_or_key + read -s -p "비밀번호를 입력하세요:" password_or_key echo # 换行 auth_method="password" ;; 2) - echo "키 내용을 붙여 넣으십시오 (붙여 넣기 후 Enter Enter를 두 번 누릅니다) :" + echo "주요 내용을 붙여넣으세요(붙인 후 Enter를 두 번 누르세요)." local password_or_key="" while IFS= read -r line; do - # 입력이 비어 있고 키 컨텐츠에 이미 시작이 포함되어 있으면 입력이 끝납니다. + # 입력이 빈 줄이고 키 내용에 이미 시작 부분이 포함된 경우 입력을 종료합니다. if [[ -z "$line" && "$password_or_key" == *"-----BEGIN"* ]]; then break fi - # 첫 번째 줄이거나 키 컨텐츠가 입력 된 경우 계속 추가하십시오. + # 첫 번째 줄이거나 이미 핵심 내용 입력을 시작했다면 계속해서 추가하세요. if [[ -n "$line" || "$password_or_key" == *"-----BEGIN"* ]]; then password_or_key+="${line}"$'\n' fi done - # 주요 내용인지 확인하십시오 + # 핵심 내용인지 확인해보세요 if [[ "$password_or_key" == *"-----BEGIN"* && "$password_or_key" == *"PRIVATE KEY-----"* ]]; then local key_file="$KEY_DIR/${name}_sync.key" echo -n "$password_or_key" > "$key_file" @@ -6162,47 +6609,47 @@ add_task() { password_or_key="$key_file" auth_method="key" else - echo "잘못된 키 컨텐츠!" + echo "잘못된 키 콘텐츠입니다!" return fi ;; *) - echo "잘못된 선택!" + echo "잘못된 선택입니다!" return ;; esac - echo "동기화 모드를 선택하십시오 :" - echo "1. 표준 모드 (-avz)" - echo "2. 대상 파일 삭제 (-avz-delete)" - read -e -p "선택하십시오 (1/2) :" mode + echo "동기화 모드를 선택하십시오:" + echo "1. 표준 모드(-avz)" + echo "2. 대상 파일 삭제(-avz --delete)" + read -e -p "(1/2)을 선택하세요:" mode case $mode in 1) options="-avz" ;; 2) options="-avz --delete" ;; - *) echo "유효하지 않은 선택, 기본값 -AVZ를 사용하십시오"; options="-avz" ;; + *) echo "선택이 잘못되었습니다. 기본값 -avz를 사용하세요."; options="-avz" ;; esac echo "$name|$local_path|$remote|$remote_path|$port|$options|$auth_method|$password_or_key" >> "$CONFIG_FILE" install rsync rsync - echo "작업을 저장했습니다!" + echo "임무가 저장되었습니다!" } -# 작업을 삭제하십시오 +# 할 일 삭제 delete_task() { - send_stats "동기화 작업을 삭제합니다" - read -e -p "삭제하려면 작업 번호를 입력하십시오." num + send_stats "동기화 작업 삭제" + read -e -p "삭제할 작업 번호를 입력하세요:" num local task=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$task" ]]; then - echo "오류 : 해당 작업을 찾을 수 없었습니다." + echo "오류: 해당 작업을 찾을 수 없습니다." return fi IFS='|' read -r name local_path remote remote_path port options auth_method password_or_key <<< "$task" - # 작업이 키 파일을 사용하는 경우 키 파일을 삭제하십시오. + # 작업이 키 파일을 사용하는 경우 키 파일을 삭제하세요. if [[ "$auth_method" == "key" && "$password_or_key" == "$KEY_DIR"* ]]; then rm -f "$password_or_key" fi @@ -6213,12 +6660,12 @@ delete_task() { run_task() { - send_stats "동기화 작업을 수행하십시오" + send_stats "동기화 작업 수행" CONFIG_FILE="$HOME/.rsync_tasks" CRON_FILE="$HOME/.rsync_cron" - # 매개 변수를 분석하십시오 + # 매개변수 구문 분석 local direction="push" # 默认是推送到远端 local num @@ -6229,51 +6676,51 @@ run_task() { num="$1" fi - # 들어오는 작업 번호가없는 경우 사용자에게 입력하라는 메시지를 표시하십시오. + # 작업 번호가 전달되지 않으면 사용자에게 입력하라는 메시지가 표시됩니다. if [[ -z "$num" ]]; then - read -e -p "실행할 작업 번호를 입력하십시오." num + read -e -p "실행할 작업 번호를 입력하세요:" num fi local task=$(sed -n "${num}p" "$CONFIG_FILE") if [[ -z "$task" ]]; then - echo "오류 : 작업이 찾을 수 없었습니다!" + echo "오류: 작업을 찾을 수 없습니다!" return fi IFS='|' read -r name local_path remote remote_path port options auth_method password_or_key <<< "$task" - # 동기화 방향에 따라 소스 및 대상 경로를 조정하십시오 + # 동기화 방향에 따라 소스 및 대상 경로 조정 if [[ "$direction" == "pull" ]]; then - echo "로컬로 동기화를 당기기 :$remote:$local_path -> $remote_path" + echo "로컬로 가져오기 및 동기화:$remote:$local_path -> $remote_path" source="$remote:$local_path" destination="$remote_path" else - echo "동기화를 원격 끝으로 푸시합니다.$local_path -> $remote:$remote_path" + echo "원격 끝에 푸시 및 동기화:$local_path -> $remote:$remote_path" source="$local_path" destination="$remote:$remote_path" fi - # SSH 연결 공통 매개 변수를 추가하십시오 + # SSH 연결 공통 매개변수 추가 local ssh_options="-p $port -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" if [[ "$auth_method" == "password" ]]; then if ! command -v sshpass &> /dev/null; then - echo "오류 : Sshpass가 설치되지 않았습니다. 먼저 Sshpass를 설치하십시오." - echo "설치 방법 :" + echo "오류: sshpass가 설치되지 않았습니다. 먼저 sshpass를 설치하십시오." + echo "설치 방법:" echo " - Ubuntu/Debian: apt install sshpass" echo " - CentOS/RHEL: yum install sshpass" return fi sshpass -p "$password_or_key" rsync $options -e "ssh $ssh_options" "$source" "$destination" else - # 키 파일이 존재하는지 여부와 권한이 올바른지 확인 + # 키 파일이 존재하는지, 권한이 올바른지 확인하세요. if [[ ! -f "$password_or_key" ]]; then - echo "오류 : 키 파일이 존재하지 않습니다.$password_or_key" + echo "오류: 키 파일이 존재하지 않습니다:$password_or_key" return fi if [[ "$(stat -c %a "$password_or_key")" != "600" ]]; then - echo "경고 : 키 파일 권한이 잘못되었고 수리 중입니다 ..." + echo "경고: 잘못된 키 파일 권한, 수정 중..." chmod 600 "$password_or_key" fi @@ -6283,30 +6730,30 @@ run_task() { if [[ $? -eq 0 ]]; then echo "동기화가 완료되었습니다!" else - echo "동기화 실패! 다음을 확인하십시오." - echo "1. 네트워크 연결이 정상입니까?" - echo "2. 원격 호스트가 액세스 할 수 있습니까?" - echo "3. 인증 정보가 정확합니까?" - echo "4. 로컬 및 원격 디렉토리에 올바른 액세스 권한이 있습니까?" + echo "동기화에 실패했습니다! 다음 사항을 확인하세요." + echo "1. 네트워크 연결이 정상인가요?" + echo "2. 원격 호스트에 접근 가능한지 여부" + echo "3. 인증정보가 정확합니까?" + echo "4. 로컬 및 원격 디렉터리에 올바른 액세스 권한이 있습니까?" fi } -# 시간이 정한 작업을 만듭니다 +# 예약된 작업 만들기 schedule_task() { - send_stats "동기화 타이밍 작업을 추가하십시오" + send_stats "동기화 예약 작업 추가" - read -e -p "정기적으로 동기화 할 작업 번호를 입력하십시오." num + read -e -p "정기적으로 동기화할 작업 번호를 입력하세요:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then - echo "오류 : 유효한 작업 번호를 입력하십시오!" + echo "오류: 유효한 작업 번호를 입력하십시오!" return fi - echo "시간이 정한 실행 간격을 선택하십시오." - echo "1) 한 시간에 한 번 실행하십시오" - echo "2) 하루에 한 번 수행하십시오" - echo "3) 일주일에 한 번 실행하십시오" - read -e -p "옵션을 입력하십시오 (1/2/3) :" interval + echo "예약된 실행 간격을 선택하십시오." + echo "1) 매 시간마다 한 번씩 실행" + echo "2) 하루에 한 번 실행" + echo "3) 일주일에 한 번 실행" + read -e -p "옵션을 입력하세요(1/2/3):" interval local random_minute=$(shuf -i 0-59 -n 1) # 生成 0-59 之间的随机分钟数 local cron_time="" @@ -6314,42 +6761,42 @@ schedule_task() { 1) cron_time="$random_minute * * * *" ;; # 每小时,随机分钟执行 2) cron_time="$random_minute 0 * * *" ;; # 每天,随机分钟执行 3) cron_time="$random_minute 0 * * 1" ;; # 每周,随机分钟执行 - *) echo "오류 : 유효한 옵션을 입력하십시오!" ; return ;; + *) echo "오류: 유효한 옵션을 입력하십시오!" ; return ;; esac local cron_job="$cron_time k rsync_run $num" local cron_job="$cron_time k rsync_run $num" - # 동일한 작업이 이미 존재하는지 확인하십시오 + # 동일한 작업이 이미 존재하는지 확인하세요. if crontab -l | grep -q "k rsync_run $num"; then - echo "오류 :이 작업의 타이밍 동기화가 이미 존재합니다!" + echo "오류: 이 작업에 대해 예약된 동기화가 이미 존재합니다!" return fi - # 사용자에게 크론AB를 만듭니다 + # 사용자의 crontab에 생성 (crontab -l 2>/dev/null; echo "$cron_job") | crontab - - echo "타이밍 작업이 만들어졌습니다.$cron_job" + echo "예약된 작업이 생성되었습니다:$cron_job" } -# 예정된 작업을 봅니다 +# 예약된 작업 보기 view_tasks() { - echo "현재 타이밍 작업 :" + echo "현재 예약된 작업:" echo "---------------------------------" crontab -l | grep "k rsync_run" echo "---------------------------------" } -# 타이밍 작업을 삭제하십시오 +# 예약된 작업 삭제 delete_task_schedule() { - send_stats "동기화 타이밍 작업을 삭제합니다" - read -e -p "삭제하려면 작업 번호를 입력하십시오." num + send_stats "동기화 예약 작업 삭제" + read -e -p "삭제할 작업 번호를 입력하세요:" num if ! [[ "$num" =~ ^[0-9]+$ ]]; then - echo "오류 : 유효한 작업 번호를 입력하십시오!" + echo "오류: 유효한 작업 번호를 입력하십시오!" return fi crontab -l | grep -v "k rsync_run $num" | crontab - - echo "삭제 된 작업 번호$num타이밍 작업" + echo "태스크 번호가 삭제되었습니다.$num예약된 작업" } @@ -6360,20 +6807,20 @@ rsync_manager() { while true; do clear - echo "RSYNC 원격 동기화 도구" - echo "원격 디렉토리 간의 동기화는 증분 동기화, 효율적이고 안정적인 지원을 지원합니다." + echo "Rsync 원격 동기화 도구" + echo "원격 디렉터리 간의 동기화는 효율적이고 안정적인 증분 동기화를 지원합니다." echo "---------------------------------" list_tasks echo view_tasks echo - echo "1. 새 작업 생성 2. 작업을 삭제하십시오" - echo "3. 원격 끝에 로컬 동기화 수행 4. 로컬 엔드에 대한 원격 동기화 수행" - echo "5. 타이밍 작업 만들기 6. 타이밍 작업 삭제" + echo "1. 새 작업 생성 2. 작업 삭제" + echo "3. 원격 사이트에 대한 로컬 동기화 수행 4. 로컬 사이트에 대한 원격 동기화 수행" + echo "5. 예약된 작업 생성 6. 예약된 작업 삭제" echo "---------------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "---------------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case $choice in 1) add_task ;; 2) delete_task ;; @@ -6382,9 +6829,9 @@ rsync_manager() { 5) schedule_task ;; 6) delete_task_schedule ;; 0) break ;; - *) echo "잘못된 선택, 다시 시도하십시오." ;; + *) echo "선택이 잘못되었습니다. 다시 시도해 주세요." ;; esac - read -e -p "계속하려면 Enter를 누르십시오 ..." + read -e -p "계속하려면 Enter를 누르세요..." done } @@ -6396,7 +6843,7 @@ rsync_manager() { -linux_ps() { +linux_info() { clear send_stats "시스템 정보 쿼리" @@ -6443,45 +6890,49 @@ linux_ps() { local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1 % 3600) / 60); if (run_days > 0) printf("%d天 ", run_days); if (run_hours > 0) printf("%d时 ", run_hours); printf("%d分\n", run_minutes)}') + local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1% 3600) / 60); if (run_days > 0) printf("%d day ", run_days); if (run_hours > 0) printf("%d시간 ", run_hours); printf("%d분\n", run_mins)}') local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" echo -e "시스템 정보 쿼리" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}호스트 이름 :${gl_bai}$hostname" - echo -e "${gl_kjlan}시스템 버전 :${gl_bai}$os_info" - echo -e "${gl_kjlan}리눅스 버전 :${gl_bai}$kernel_version" + echo -e "${gl_kjlan}호스트 이름:${gl_bai}$hostname" + echo -e "${gl_kjlan}시스템 버전:${gl_bai}$os_info" + echo -e "${gl_kjlan}리눅스 버전:${gl_bai}$kernel_version" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU 아키텍처 :${gl_bai}$cpu_arch" - echo -e "${gl_kjlan}CPU 모델 :${gl_bai}$cpu_info" - echo -e "${gl_kjlan}CPU 코어 수 :${gl_bai}$cpu_cores" - echo -e "${gl_kjlan}CPU 주파수 :${gl_bai}$cpu_freq" + echo -e "${gl_kjlan}CPU 아키텍처:${gl_bai}$cpu_arch" + echo -e "${gl_kjlan}CPU 모델:${gl_bai}$cpu_info" + echo -e "${gl_kjlan}CPU 코어 수:${gl_bai}$cpu_cores" + echo -e "${gl_kjlan}CPU 주파수:${gl_bai}$cpu_freq" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}CPU 점유 :${gl_bai}$cpu_usage_percent%" - echo -e "${gl_kjlan}시스템 부하 :${gl_bai}$load" - echo -e "${gl_kjlan}물리적 기억 :${gl_bai}$mem_info" - echo -e "${gl_kjlan}가상 메모리 :${gl_bai}$swap_info" - echo -e "${gl_kjlan}하드 디스크 직업 :${gl_bai}$disk_info" + echo -e "${gl_kjlan}CPU 사용량:${gl_bai}$cpu_usage_percent%" + echo -e "${gl_kjlan}시스템 부하:${gl_bai}$load" + echo -e "${gl_kjlan}TCP|UDP 연결 수:${gl_bai}$tcp_count|$udp_count" + echo -e "${gl_kjlan}물리적 메모리:${gl_bai}$mem_info" + echo -e "${gl_kjlan}가상 메모리:${gl_bai}$swap_info" + echo -e "${gl_kjlan}하드 드라이브 사용량:${gl_bai}$disk_info" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}총 수신 :${gl_bai}$rx" - echo -e "${gl_kjlan}총 보내기 :${gl_bai}$tx" + echo -e "${gl_kjlan}받은 총액:${gl_bai}$rx" + echo -e "${gl_kjlan}보낸 총액:${gl_bai}$tx" echo -e "${gl_kjlan}-------------" - echo -e "${gl_kjlan}네트워크 알고리즘 :${gl_bai}$congestion_algorithm $queue_algorithm" + echo -e "${gl_kjlan}네트워크 알고리즘:${gl_bai}$congestion_algorithm $queue_algorithm" echo -e "${gl_kjlan}-------------" echo -e "${gl_kjlan}연산자:${gl_bai}$isp_info" if [ -n "$ipv4_address" ]; then - echo -e "${gl_kjlan}IPv4 주소 :${gl_bai}$ipv4_address" + echo -e "${gl_kjlan}IPv4 주소:${gl_bai}$ipv4_address" fi if [ -n "$ipv6_address" ]; then - echo -e "${gl_kjlan}IPv6 주소 :${gl_bai}$ipv6_address" + echo -e "${gl_kjlan}IPv6 주소:${gl_bai}$ipv6_address" fi - echo -e "${gl_kjlan}DNS 주소 :${gl_bai}$dns_addresses" - echo -e "${gl_kjlan}지리적 위치 :${gl_bai}$country $city" - echo -e "${gl_kjlan}시스템 시간 :${gl_bai}$timezone $current_time" + echo -e "${gl_kjlan}DNS 주소:${gl_bai}$dns_addresses" + echo -e "${gl_kjlan}위치:${gl_bai}$country $city" + echo -e "${gl_kjlan}시스템 시간:${gl_bai}$timezone $current_time" echo -e "${gl_kjlan}-------------" echo -e "${gl_kjlan}실행 시간:${gl_bai}$runtime" echo @@ -6499,108 +6950,108 @@ linux_tools() { # send_stats "기본 도구" echo -e "기본 도구" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}컬 다운로드 도구${gl_huang}★${gl_bai} ${gl_kjlan}2. ${gl_bai}WGET 다운로드 도구${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}3. ${gl_bai}Sudo Super Management 권한 도구${gl_kjlan}4. ${gl_bai}소사이어티 커뮤니케이션 연결 도구" - echo -e "${gl_kjlan}5. ${gl_bai}HTOP 시스템 모니터링 도구${gl_kjlan}6. ${gl_bai}IFTOP 네트워크 트래픽 모니터링 도구" - echo -e "${gl_kjlan}7. ${gl_bai}압축 지퍼 압축 압축 압축 도구${gl_kjlan}8. ${gl_bai}TAR GZ 압축 감압 도구" - echo -e "${gl_kjlan}9. ${gl_bai}Tmux 다중 채널 배경 달리기 도구${gl_kjlan}10. ${gl_bai}FFMPEG 비디오 라이브 스트리밍 도구 인코딩" + echo -e "${gl_kjlan}1. ${gl_bai}컬 다운로드 도구${gl_huang}★${gl_bai} ${gl_kjlan}2. ${gl_bai}wget 다운로드 도구${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}3. ${gl_bai}sudo 최고 관리 권한 도구${gl_kjlan}4. ${gl_bai}socat 통신 연결 도구" + echo -e "${gl_kjlan}5. ${gl_bai}htop 시스템 모니터링 도구${gl_kjlan}6. ${gl_bai}iftop 네트워크 트래픽 모니터링 도구" + echo -e "${gl_kjlan}7. ${gl_bai}unzip ZIP 압축 및 압축 풀기 도구${gl_kjlan}8. ${gl_bai}tar GZ 압축 및 압축 해제 도구" + echo -e "${gl_kjlan}9. ${gl_bai}tmux 다중 채널 백그라운드 실행 도구${gl_kjlan}10. ${gl_bai}ffmpeg 비디오 인코딩 라이브 스트리밍 도구" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}BTOP 최신 모니터링 도구${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}범위 파일 관리 도구" - echo -e "${gl_kjlan}13. ${gl_bai}NCDU 디스크 직업 관찰 도구${gl_kjlan}14. ${gl_bai}FZF 글로벌 검색 도구" + echo -e "${gl_kjlan}11. ${gl_bai}btop 최신 모니터링 도구${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}레인저 파일 관리 도구" + echo -e "${gl_kjlan}13. ${gl_bai}ncdu 디스크 사용량 보기 도구${gl_kjlan}14. ${gl_bai}fzf 글로벌 검색 도구" echo -e "${gl_kjlan}15. ${gl_bai}vim 텍스트 편집기${gl_kjlan}16. ${gl_bai}나노 텍스트 편집기${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}GIT 버전 제어 시스템" + echo -e "${gl_kjlan}17. ${gl_bai}Git 버전 관리 시스템${gl_kjlan}18. ${gl_bai}오픈코드 AI 프로그래밍 도우미${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}매트릭스 화면 보증${gl_kjlan}22. ${gl_bai}열차 스크린 보안" - echo -e "${gl_kjlan}26. ${gl_bai}테트리스 게임${gl_kjlan}27. ${gl_bai}뱀 먹는 게임" - echo -e "${gl_kjlan}28. ${gl_bai}우주 침략자 게임" + echo -e "${gl_kjlan}21. ${gl_bai}매트릭스 스크린세이버${gl_kjlan}22. ${gl_bai}달리는 기차 화면 보호기" + echo -e "${gl_kjlan}26. ${gl_bai}테트리스 미니 게임${gl_kjlan}27. ${gl_bai}뱀 미니게임" + echo -e "${gl_kjlan}28. ${gl_bai}우주 침략자 미니 게임" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}모두 설치하십시오${gl_kjlan}32. ${gl_bai}모든 설치 (스크린 세이버 및 게임 제외)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}모든 것을 제거하십시오" + echo -e "${gl_kjlan}31. ${gl_bai}모두 설치${gl_kjlan}32. ${gl_bai}모두 설치(화면 보호기 및 게임 제외)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}모두 제거" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}지정된 도구를 설치하십시오${gl_kjlan}42. ${gl_bai}지정된 도구를 제거하십시오" + echo -e "${gl_kjlan}41. ${gl_bai}지정된 도구 설치${gl_kjlan}42. ${gl_bai}지정된 도구 제거" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) clear install curl clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." curl --help - send_stats "컬을 설치하십시오" + send_stats "컬 설치" ;; 2) clear install wget clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." wget --help - send_stats "wget을 설치하십시오" + send_stats "wget 설치" ;; 3) clear install sudo clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." sudo --help - send_stats "Sudo를 설치하십시오" + send_stats "sudo 설치" ;; 4) clear install socat clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." socat -h - send_stats "Socat을 설치하십시오" + send_stats "socat 설치" ;; 5) clear install htop clear htop - send_stats "HTOP를 설치하십시오" + send_stats "htop 설치" ;; 6) clear install iftop clear iftop - send_stats "iftop을 설치하십시오" + send_stats "iftop 설치" ;; 7) clear install unzip clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." unzip - send_stats "압축을 설치하십시오" + send_stats "설치압축 해제" ;; 8) clear install tar clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." tar --help - send_stats "타르를 설치하십시오" + send_stats "타르 설치" ;; 9) clear install tmux clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." tmux --help - send_stats "tmux를 설치하십시오" + send_stats "tmux 설치" ;; 10) clear install ffmpeg clear - echo "도구가 설치되었으며 사용법은 다음과 같습니다." + echo "도구가 설치되었으며 다음과 같이 사용됩니다." ffmpeg --help - send_stats "FFMPEG를 설치하십시오" + send_stats "ffmpeg 설치" ;; 11) @@ -6608,7 +7059,7 @@ linux_tools() { install btop clear btop - send_stats "Btop을 설치하십시오" + send_stats "btop 설치" ;; 12) clear @@ -6617,7 +7068,7 @@ linux_tools() { clear ranger cd ~ - send_stats "레인저를 설치하십시오" + send_stats "레인저 설치" ;; 13) clear @@ -6626,7 +7077,7 @@ linux_tools() { clear ncdu cd ~ - send_stats "NCDU를 설치하십시오" + send_stats "ncdu 설치" ;; 14) clear @@ -6635,7 +7086,7 @@ linux_tools() { clear fzf cd ~ - send_stats "FZF를 설치하십시오" + send_stats "fzf 설치" ;; 15) clear @@ -6644,7 +7095,7 @@ linux_tools() { clear vim -h cd ~ - send_stats "VIM을 설치하십시오" + send_stats "vim 설치" ;; 16) clear @@ -6653,7 +7104,7 @@ linux_tools() { clear nano -h cd ~ - send_stats "나노를 설치하십시오" + send_stats "나노 설치" ;; @@ -6664,75 +7115,89 @@ linux_tools() { clear git --help cd ~ - send_stats "git을 설치하십시오" + send_stats "자식 설치" + ;; + + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "오픈코드 설치" ;; + 21) clear install cmatrix clear cmatrix - send_stats "cmatrix를 설치하십시오" + send_stats "cmatrix 설치" ;; 22) clear install sl clear sl - send_stats "SL을 설치하십시오" + send_stats "sl 설치" ;; 26) clear install bastet clear bastet - send_stats "Bastet을 설치하십시오" + send_stats "바스테트 설치" ;; 27) clear install nsnake clear nsnake - send_stats "NSNAKE를 설치하십시오" + send_stats "nsnake 설치" ;; + 28) clear install ninvaders clear ninvaders - send_stats "Ninvaders를 설치하십시오" + send_stats "닌베이더 설치" ;; 31) clear - send_stats "모두 설치하십시오" + send_stats "모두 설치" install curl wget sudo socat htop iftop unzip tar tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git ;; 32) clear - send_stats "모든 설치 (게임 및 화면 보호기 제외)" + send_stats "모두 설치(게임 및 화면 보호기 제외)" install curl wget sudo socat htop iftop unzip tar tmux ffmpeg btop ranger ncdu fzf vim nano git ;; 33) clear - send_stats "모든 것을 제거하십시오" + send_stats "모두 제거" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) clear - read -e -p "설치된 도구 이름 (WGET CURL SUDO HTOP)을 입력하십시오." installname + read -e -p "설치된 도구 이름을 입력하십시오(wget 컬 sudo htop):" installname install $installname - send_stats "지정된 소프트웨어를 설치하십시오" + send_stats "지정된 소프트웨어 설치" ;; 42) clear - read -e -p "제거되지 않은 도구 이름 (HTOP UFW TMUX CMATRIX)을 입력하십시오." removename + read -e -p "제거된 도구 이름(htop ufw tmux cmatrix)을 입력하십시오." removename remove $removename - send_stats "지정된 소프트웨어를 제거하십시오" + send_stats "지정된 소프트웨어 제거" ;; 0) @@ -6740,7 +7205,7 @@ linux_tools() { ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -6760,24 +7225,24 @@ linux_bbr() { clear local congestion_algorithm=$(sysctl -n net.ipv4.tcp_congestion_control) local queue_algorithm=$(sysctl -n net.core.default_qdisc) - echo "현재 TCP 차단 알고리즘 :$congestion_algorithm $queue_algorithm" + echo "현재 TCP 차단 알고리즘:$congestion_algorithm $queue_algorithm" echo "" echo "BBR 관리" echo "------------------------" - echo "1. BBRV3 켜기 2. BBRV3 끄기 (재시작)" + echo "1. BBRv3를 켭니다. 2. BBRv3을 끕니다(다시 시작됩니다)." echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) bbr_on - send_stats "알파인 활성화 BBR3" + send_stats "알파인이 열립니다 bbr3" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6801,69 +7266,397 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # Send_stats "Docker Management" - echo -e "도커 관리" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Docker 환경을 설치하고 업데이트하십시오${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}Docker Global Status를 봅니다${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}도커 컨테이너 관리${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}도커 이미지 관리" - echo -e "${gl_kjlan}5. ${gl_bai}도커 네트워크 관리" - echo -e "${gl_kjlan}6. ${gl_bai}도커 볼륨 관리" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}7. ${gl_bai}쓸모없는 도커 컨테이너 및 미러 네트워크 데이터 볼륨을 청소하십시오" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}8. ${gl_bai}Docker 소스를 교체하십시오" - echo -e "${gl_kjlan}9. ${gl_bai}daemon.json 파일 편집" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}Docker-IPV6 액세스를 활성화하십시오" - echo -e "${gl_kjlan}12. ${gl_bai}Docker-IPV6 액세스를 닫습니다" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}20. ${gl_bai}Docker 환경을 제거하십시오" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' - case $sub_choice in - 1) - clear - send_stats "Docker 환경을 설치하십시오" - install_add_docker + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } - ;; - 2) - clear - local container_count=$(docker ps -a -q 2>/dev/null | wc -l) - local image_count=$(docker images -q 2>/dev/null | wc -l) - local network_count=$(docker network ls -q 2>/dev/null | wc -l) - local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}현재 백업 목록:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "백업 없음" + } - send_stats "도커 글로벌 상태" - echo "도커 버전" - docker -v - docker compose version - echo "" - echo -e "도커 이미지 :${gl_lv}$image_count${gl_bai} " - docker image ls - echo "" - echo -e "도커 컨테이너 :${gl_lv}$container_count${gl_bai}" - docker ps -a - echo "" - echo -e "도커 볼륨 :${gl_lv}$volume_count${gl_bai}" - docker volume ls - echo "" - echo -e "도커 네트워크 :${gl_lv}$network_count${gl_bai}" - docker network ls - echo "" + + # ---------------------------- + # 지원 + # ---------------------------- + backup_docker() { + send_stats "도커 백업" + + echo -e "${YELLOW}Docker 컨테이너 백업 중...${NC}" + docker ps --format '{{.Names}}' + read -e -p "백업할 컨테이너의 이름을 입력하십시오(실행 중인 모든 컨테이너를 백업하려면 여러 개의 공백을 구분하고 Enter 키를 누르십시오)." containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}컨테이너를 찾을 수 없습니다.${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# 자동으로 생성된 복원 스크립트" >> "$RESTORE_SCRIPT" + + # 반복되는 패키징을 피하기 위해 패키징된 Compose 프로젝트 경로를 기록하세요. + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}백업 컨테이너:$c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}감지됨$c도커 작성 컨테이너입니다${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "작성 디렉터리가 감지되지 않습니다. 경로를 수동으로 입력하세요." project_dir + fi + + # Compose 프로젝트가 이미 패키징된 경우 건너뛰세요. + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}프로젝트 작성 [$project_name] 이미 백업되어 있으니 반복 패키징은 건너뛰세요...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose 복원:$project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}프로젝트 작성 [$project_name] 포장:${project_dir}${NC}" + else + echo -e "${RED}docker-compose.yml을 찾을 수 없습니다. 이 컨테이너를 건너뛰는 중입니다...${NC}" + fi + else + # 일반 컨테이너 백업 볼륨 + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "포장량:$path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # 포트 + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # 환경 변수 + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # 볼륨 매핑 + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # 거울 + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# 복원 컨테이너:$c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # /home/docker 아래의 모든 파일을 백업합니다(하위 디렉터리 제외). + if [ -d "/home/docker" ]; then + echo -e "${BLUE}/home/docker 아래의 파일을 백업합니다...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}/home/docker 아래의 파일은 다음과 같이 패키지되었습니다.${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}백업 완료:${BACKUP_DIR}${NC}" + echo -e "${GREEN}사용 가능한 복원 스크립트:${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # 절감 + # ---------------------------- + restore_docker() { + + send_stats "도커 복원" + read -e -p "복원할 백업 디렉터리를 입력하십시오:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}백업 디렉터리가 존재하지 않습니다.${NC}"; return; } + + echo -e "${BLUE}복원 작업을 시작하는 중...${NC}" + + install tar jq gzip + install_docker + + # --------- Compose 프로젝트 복원 우선순위 지정 --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "원래 경로를 찾을 수 없습니다. 복원 디렉터리 경로를 입력하십시오:" original_path + + # Compose 프로젝트의 컨테이너가 이미 실행 중인지 확인하세요. + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}프로젝트 작성 [$project_name] 컨테이너가 이미 실행 중입니다. 복원을 건너뛰세요...${NC}" + continue + fi + + read -e -p "Compose 프로젝트 복원 확인 [$project_name] 경로 [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "새 복원 경로를 입력하십시오." original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}프로젝트 작성 [$project_name]는 다음 위치로 추출되었습니다.$original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}프로젝트 작성 [$project_name] 복원 완료!${NC}" + fi + done + + # --------- 일반 컨테이너를 계속 복원합니다 --------- + echo -e "${BLUE}일반 Docker 컨테이너 확인 및 복원...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}처리용기:$container${NC}" + + # 컨테이너가 이미 존재하고 실행 중인지 확인하세요. + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}컨테이너 [$container] 이미 실행 중입니다. 복원을 건너뛰는 중...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}미러 정보를 찾을 수 없습니다. 건너뛰세요:$container${NC}"; continue; } + + # 포트 매핑 + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # 환경 변수 + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # 볼륨 매핑 + 볼륨 데이터 복구 + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "볼륨 데이터 복구:$VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # 기존이지만 실행되지 않는 컨테이너 삭제 + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}컨테이너 [$container]가 있지만 실행 중이 아닙니다. 이전 컨테이너를 삭제하세요...${NC}" + docker rm -f "$container" + fi + + # 컨테이너 시작 + echo "복원 명령을 실행합니다: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}공통 컨테이너에 대한 백업 정보가 없습니다.${NC}" + + # /home/docker 아래의 파일 복원 + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}/home/docker 아래의 파일을 복원하는 중...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}/home/docker 아래의 파일이 복원되었습니다.${NC}" + else + echo -e "${YELLOW}/home/docker 아래의 파일 백업을 찾을 수 없습니다. 건너뛰는 중...${NC}" + fi + + + } + + + # ---------------------------- + # 이주하다 + # ---------------------------- + migrate_docker() { + send_stats "도커 마이그레이션" + install jq + read -e -p "마이그레이션할 백업 디렉터리를 입력하세요." BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}백업 디렉터리가 존재하지 않습니다.${NC}"; return; } + + read -e -p "대상 서버 IP:" TARGET_IP + read -e -p "대상 서버 SSH 사용자 이름:" TARGET_USER + read -e -p "대상 서버 SSH 포트 [기본값 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}백업 전송 중...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # 키를 사용하여 로그인 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # 백업 삭제 + # ---------------------------- + delete_backup() { + send_stats "Docker 백업 파일 삭제" + read -e -p "삭제할 백업 디렉터리를 입력하십시오:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}백업 디렉터리가 존재하지 않습니다.${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}삭제된 백업:${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # 메인 메뉴 + # ---------------------------- + main_menu() { + send_stats "Docker 백업 마이그레이션 복원" + while true; do + clear + echo "------------------------" + echo -e "Docker 백업/마이그레이션/복원 도구" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. 도커 프로젝트 백업" + echo -e "2. 도커 프로젝트 마이그레이션" + echo -e "3. 도커 프로젝트 복원" + echo -e "4. docker 프로젝트 백업 파일 삭제" + echo "------------------------" + echo -e "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택하세요:" choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}잘못된 옵션${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "도커 관리" + echo -e "도커 관리" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}Docker 환경 설치 및 업데이트${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}Docker 전역 상태 보기${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}도커 컨테이너 관리${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}도커 이미지 관리" + echo -e "${gl_kjlan}5. ${gl_bai}도커 네트워크 관리" + echo -e "${gl_kjlan}6. ${gl_bai}도커 볼륨 관리" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}7. ${gl_bai}쓸모없는 도커 컨테이너를 정리하고 네트워크 데이터 볼륨을 미러링하세요." + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}8. ${gl_bai}Docker 소스 변경" + echo -e "${gl_kjlan}9. ${gl_bai}daemon.json 파일 편집" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}11. ${gl_bai}Docker-ipv6 액세스 활성화" + echo -e "${gl_kjlan}12. ${gl_bai}Docker-ipv6 액세스 끄기" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}Docker 환경 백업/마이그레이션/복원" + echo -e "${gl_kjlan}20. ${gl_bai}Docker 환경 제거" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "선택사항을 입력하세요:" sub_choice + + case $sub_choice in + 1) + clear + send_stats "도커 환경 설치" + install_add_docker + + ;; + 2) + clear + local container_count=$(docker ps -a -q 2>/dev/null | wc -l) + local image_count=$(docker images -q 2>/dev/null | wc -l) + local network_count=$(docker network ls -q 2>/dev/null | wc -l) + local volume_count=$(docker volume ls -q 2>/dev/null | wc -l) + + send_stats "도커 전역 상태" + echo "도커 버전" + docker -v + docker compose version + + echo "" + echo -e "도커 이미지:${gl_lv}$image_count${gl_bai} " + docker image ls + echo "" + echo -e "도커 컨테이너:${gl_lv}$container_count${gl_bai}" + docker ps -a + echo "" + echo -e "Docker 볼륨:${gl_lv}$volume_count${gl_bai}" + docker volume ls + echo "" + echo -e "도커 네트워크:${gl_lv}$network_count${gl_bai}" + docker network ls + echo "" ;; 3) @@ -6884,7 +7677,7 @@ linux_docker() { echo "------------------------------------------------------------" container_ids=$(docker ps -q) - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "컨테이너 이름" "네트워크 이름" "IP 주소" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") @@ -6901,36 +7694,36 @@ linux_docker() { done echo "" - echo "네트워크 작동" + echo "네트워크 운영" echo "------------------------" - echo "1. 네트워크를 만듭니다" - echo "2. 인터넷에 가입하십시오" - echo "3. 네트워크를 종료하십시오" - echo "4. 네트워크를 삭제합니다" + echo "1. 네트워크 생성" + echo "2. 네트워크에 가입하세요" + echo "3. 네트워크 종료" + echo "4. 네트워크 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "네트워크를 만듭니다" - read -e -p "새 네트워크 이름 설정 :" dockernetwork + send_stats "네트워크 생성" + read -e -p "새 네트워크 이름 설정:" dockernetwork docker network create $dockernetwork ;; 2) - send_stats "인터넷에 가입하십시오" - read -e -p "네트워크 이름에 가입 :" dockernetwork - read -e -p "해당 컨테이너는 네트워크에 추가됩니다 (여러 컨테이너 이름은 공간으로 분리됩니다)." dockernames + send_stats "네트워크에 가입하세요" + read -e -p "네트워크 이름 추가:" dockernetwork + read -e -p "네트워크에 참여하는 컨테이너(여러 컨테이너 이름을 공백으로 구분하세요):" dockernames for dockername in $dockernames; do docker network connect $dockernetwork $dockername done ;; 3) - send_stats "인터넷에 가입하십시오" - read -e -p "종료 네트워크 이름 :" dockernetwork - read -e -p "해당 컨테이너는 네트워크를 종료합니다 (여러 컨테이너 이름은 공간별로 분리됩니다)." dockernames + send_stats "네트워크에 가입하세요" + read -e -p "종료 네트워크 이름:" dockernetwork + read -e -p "해당 컨테이너는 네트워크를 종료합니다(여러 컨테이너 이름을 공백으로 구분하세요)." dockernames for dockername in $dockernames; do docker network disconnect $dockernetwork $dockername @@ -6939,8 +7732,8 @@ linux_docker() { ;; 4) - send_stats "네트워크를 삭제하십시오" - read -e -p "삭제하려면 네트워크 이름을 입력하십시오." dockernetwork + send_stats "네트워크 삭제" + read -e -p "삭제할 네트워크 이름을 입력하세요:" dockernetwork docker network rm $dockernetwork ;; @@ -6958,25 +7751,25 @@ linux_docker() { echo "도커 볼륨 목록" docker volume ls echo "" - echo "볼륨 작동" + echo "볼륨 작업" echo "------------------------" - echo "1. 새 볼륨을 만듭니다" - echo "2. 지정된 볼륨을 삭제합니다" - echo "3. 모든 볼륨을 삭제하십시오" + echo "1. 새 볼륨 생성" + echo "2. 지정된 볼륨 삭제" + echo "3. 모든 볼륨 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - send_stats "새 볼륨을 만듭니다" - read -e -p "새 볼륨 이름 설정 :" dockerjuan + send_stats "새 볼륨 생성" + read -e -p "새 볼륨 이름 설정:" dockerjuan docker volume create $dockerjuan ;; 2) - read -e -p "볼륨 삭제 이름을 입력하십시오 (공백으로 여러 볼륨 이름을 분리하십시오)." dockerjuans + read -e -p "삭제 볼륨 이름을 입력하십시오(여러 볼륨 이름을 공백으로 구분하십시오):" dockerjuans for dockerjuan in $dockerjuans; do docker volume rm $dockerjuan @@ -6985,7 +7778,7 @@ linux_docker() { ;; 3) - send_stats "모든 볼륨을 삭제하십시오" + send_stats "모든 볼륨 삭제" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定删除所有未使用的卷吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -6994,7 +7787,7 @@ linux_docker() { [Nn]) ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -7007,7 +7800,7 @@ linux_docker() { ;; 7) clear - send_stats "도커 청소" + send_stats "도커 정리" read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}将清理无用的镜像容器网络,包括停止的容器,确定清理吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -7016,7 +7809,7 @@ linux_docker() { [Nn]) ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -7033,21 +7826,29 @@ linux_docker() { restart docker ;; + + + 11) clear - send_stats "Docker V6 열기" + send_stats "도커 v6 켜짐" docker_ipv6_on ;; 12) clear - send_stats "Docker V6 레벨" + send_stats "도커 v6 닫기" docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear - send_stats "Docker는 제거합니다" + send_stats "도커 제거" read -e -p "$(echo -e "${gl_hong}注意: ${gl_bai}确定卸载docker环境吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -7059,7 +7860,7 @@ linux_docker() { [Nn]) ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -7068,7 +7869,7 @@ linux_docker() { kejilion ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -7085,44 +7886,45 @@ linux_test() { while true; do clear - # Send_stats "테스트 스크립트 컬렉션" - echo -e "스크립트 수집 테스트" + # send_stats "테스트 스크립트 수집" + echo -e "테스트 스크립트 수집" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}IP 및 잠금 해제 상태 감지" - echo -e "${gl_kjlan}1. ${gl_bai}ChatGpt는 상태 감지를 잠금 해제합니다" + echo -e "${gl_kjlan}1. ${gl_bai}ChatGPT 잠금 해제 상태 감지" echo -e "${gl_kjlan}2. ${gl_bai}지역 스트리밍 미디어 잠금 해제 테스트" - echo -e "${gl_kjlan}3. ${gl_bai}YEAHWU 스트리밍 미디어 잠금 해제 탐지" - echo -e "${gl_kjlan}4. ${gl_bai}XYKT IP 품질 신체 검사 스크립트${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}3. ${gl_bai}예우 스트리밍 미디어 잠금 해제 감지" + echo -e "${gl_kjlan}4. ${gl_bai}xykt IP 품질 확인 스크립트${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}네트워크 속도 측정" - echo -e "${gl_kjlan}11. ${gl_bai}Besttrace 3 개의 네트워크 백홀 지연 라우팅 테스트" - echo -e "${gl_kjlan}12. ${gl_bai}MTR_TRACE 3- 네트워크 백홀 라인 테스트" - echo -e "${gl_kjlan}13. ${gl_bai}Superspeed 3 Net 속도 측정" + echo -e "${gl_kjlan}네트워크 회선 속도 테스트" + echo -e "${gl_kjlan}11. ${gl_bai}besttrace 3 네트워크 백홀 지연 라우팅 테스트" + echo -e "${gl_kjlan}12. ${gl_bai}mtr_trace 삼중 네트워크 백홀 회선 테스트" + echo -e "${gl_kjlan}13. ${gl_bai}초고속 트리플 네트워크 속도 테스트" echo -e "${gl_kjlan}14. ${gl_bai}nxtrace 빠른 백홀 테스트 스크립트" - echo -e "${gl_kjlan}15. ${gl_bai}nxtrace는 ip backhaul 테스트 스크립트를 지정합니다" - echo -e "${gl_kjlan}16. ${gl_bai}Ludashi2020 3 네트워크 라인 테스트" - echo -e "${gl_kjlan}17. ${gl_bai}I-ABC 다기능 속도 테스트 스크립트" - echo -e "${gl_kjlan}18. ${gl_bai}Netquality Network 품질 신체 검사 스크립트${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}15. ${gl_bai}nxtrace는 IP 백홀 테스트 스크립트를 지정합니다." + echo -e "${gl_kjlan}16. ${gl_bai}ludashi2020 세 개의 네트워크 라인 테스트" + echo -e "${gl_kjlan}17. ${gl_bai}i-abc 다기능 속도 테스트 스크립트" + echo -e "${gl_kjlan}18. ${gl_bai}NetQuality 네트워크 품질 확인 스크립트${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}하드웨어 성능 테스트" - echo -e "${gl_kjlan}21. ${gl_bai}YABS 성능 테스트" - echo -e "${gl_kjlan}22. ${gl_bai}IICU/GB5 CPU 성능 테스트 스크립트" + echo -e "${gl_kjlan}21. ${gl_bai}Yabs 성능 테스트" + echo -e "${gl_kjlan}22. ${gl_bai}icu/gb5 CPU 성능 테스트 스크립트" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}포괄적 인 테스트" + echo -e "${gl_kjlan}종합적인 테스트" echo -e "${gl_kjlan}31. ${gl_bai}벤치 성능 테스트" - echo -e "${gl_kjlan}32. ${gl_bai}SpiritySDX 퓨전 몬스터 검토${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}32. ${gl_bai}spiritysdx 퓨전 몬스터 평가${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}Nodequality 융합 몬스터 평가${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) clear - send_stats "ChatGpt는 상태 감지를 잠금 해제합니다" + send_stats "ChatGPT 잠금 해제 상태 감지" bash <(curl -Ls https://cdn.jsdelivr.net/gh/missuo/OpenAI-Checker/openai.sh) ;; 2) @@ -7132,31 +7934,31 @@ linux_test() { ;; 3) clear - send_stats "YEAHWU 스트리밍 미디어 잠금 해제 탐지" + send_stats "예우 스트리밍 미디어 잠금 해제 감지" install wget wget -qO- ${gh_proxy}github.com/yeahwu/check/raw/main/check.sh | bash ;; 4) clear - send_stats "xykt_ip 품질 신체 검사 스크립트" + send_stats "xykt_IP 품질 확인 스크립트" bash <(curl -Ls IP.Check.Place) ;; 11) clear - send_stats "Besttrace 3 개의 네트워크 백홀 지연 라우팅 테스트" + send_stats "besttrace 삼중 네트워크 백홀 지연 라우팅 테스트" install wget wget -qO- git.io/besttrace | bash ;; 12) clear - send_stats "MTR_TRACE 3 개의 네트워크 리턴 라인 테스트" + send_stats "mtr_trace 삼중 네트워크 백홀 회선 테스트" curl ${gh_proxy}raw.githubusercontent.com/zhucaidan/mtr_trace/main/mtr_trace.sh | bash ;; 13) clear - send_stats "Superspeed 3 Net 속도 측정" + send_stats "초고속 트리플 네트워크 속도 테스트" bash <(curl -Lso- https://git.io/superspeed_uxh) ;; 14) @@ -7167,40 +7969,40 @@ linux_test() { ;; 15) clear - send_stats "nxtrace는 ip backhaul 테스트 스크립트를 지정합니다" - echo "참조 할 수있는 IP 목록" + send_stats "nxtrace는 IP 백홀 테스트 스크립트를 지정합니다." + echo "참조 IP 목록" echo "------------------------" - echo "베이징 통신 : 219.141.136.12" - echo "베이징 유니폼 : 202.106.50.1" - echo "베이징 모바일 : 221.179.155.161" - echo "상하이 통신 : 202.96.209.133" - echo "상하이 유니폼 : 210.22.97.1" - echo "상하이 모바일 : 211.136.112.200" - echo "광저우 통신 : 58.60.188.222" - echo "광저우 유니폼 : 210.21.196.6" - echo "광저우 모바일 : 120.196.165.24" - echo "청두 통신 : 61.139.2.69" - echo "청두 유니폼 : 119.6.6.6" - echo "청두 모바일 : 211.137.96.205" - echo "Hunan Telecom : 36.111.200.100" - echo "후난 유니폼 : 42.48.16.100" - echo "후난 모바일 : 39.134.254.6" + echo "베이징 통신: 219.141.136.12" + echo "베이징 유니콤: 202.106.50.1" + echo "베이징 모바일: 221.179.155.161" + echo "상하이 통신: 202.96.209.133" + echo "상하이 유니콤: 210.22.97.1" + echo "상하이 모바일: 211.136.112.200" + echo "광저우 통신: 58.60.188.222" + echo "광저우 차이나 유니콤: 210.21.196.6" + echo "광저우 모바일: 120.196.165.24" + echo "청두통신: 61.139.2.69" + echo "청두 차이나 유니콤: 119.6.6.6" + echo "청두 모바일: 211.137.96.205" + echo "후난 통신: 36.111.200.100" + echo "후난 유니콤: 42.48.16.100" + echo "후난 모바일: 39.134.254.6" echo "------------------------" - read -e -p "지정된 IP를 입력하십시오." testip + read -e -p "특정 IP를 입력하세요:" testip curl nxtrace.org/nt |bash nexttrace $testip ;; 16) clear - send_stats "Ludashi2020 3 네트워크 라인 테스트" + send_stats "ludashi2020 세 개의 네트워크 라인 테스트" curl ${gh_proxy}raw.githubusercontent.com/ludashi2020/backtrace/main/install.sh -sSf | sh ;; 17) clear - send_stats "I-ABC 다기능 속도 테스트 스크립트" + send_stats "i-abc 다기능 속도 테스트 스크립트" bash <(curl -sL ${gh_proxy}raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh) ;; @@ -7212,13 +8014,13 @@ linux_test() { 21) clear - send_stats "YABS 성능 테스트" + send_stats "Yabs 성능 테스트" check_swap curl -sL yabs.sh | bash -s -- -i -5 ;; 22) clear - send_stats "IICU/GB5 CPU 성능 테스트 스크립트" + send_stats "icu/gb5 CPU 성능 테스트 스크립트" check_swap bash <(curl -sL bash.icu/gb5) ;; @@ -7229,17 +8031,25 @@ linux_test() { curl -Lso- bench.sh | bash ;; 32) - send_stats "SpiritySDX 퓨전 몬스터 검토" + send_stats "spiritysdx 퓨전 몬스터 리뷰" + clear + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "Nodequality 융합 몬스터 평가" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -7258,49 +8068,49 @@ linux_Oracle() { send_stats "Oracle Cloud 스크립트 컬렉션" echo -e "Oracle Cloud 스크립트 컬렉션" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}유휴 기계 활성 스크립트를 설치하십시오" - echo -e "${gl_kjlan}2. ${gl_bai}유휴 기계 활성 스크립트를 제거하십시오" + echo -e "${gl_kjlan}1. ${gl_bai}유휴 머신 활성 스크립트 설치" + echo -e "${gl_kjlan}2. ${gl_bai}유휴 컴퓨터에서 활성 스크립트 제거" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}DD 다시 설치 시스템 스크립트" - echo -e "${gl_kjlan}4. ${gl_bai}형사 R 스크립트 시작" - echo -e "${gl_kjlan}5. ${gl_bai}루트 비밀번호 로그인 모드를 켭니다" - echo -e "${gl_kjlan}6. ${gl_bai}IPv6 복구 도구" + echo -e "${gl_kjlan}3. ${gl_bai}DD 재설치 시스템 스크립트" + echo -e "${gl_kjlan}4. ${gl_bai}R 형사 시작 스크립트" + echo -e "${gl_kjlan}5. ${gl_bai}ROOT 비밀번호 로그인 모드 활성화" + echo -e "${gl_kjlan}6. ${gl_bai}IPV6 복구 도구" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) clear - echo "활성 스크립트 : CPU는 10-20% 메모리를 점유합니다." - read -e -p "설치 하시겠습니까? (Y/N) :" choice + echo "활성 스크립트: CPU 사용량 10-20% 메모리 사용량 20%" + read -e -p "정말로 설치하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) install_docker - # 기본값을 설정합니다 + # 기본값 설정 local DEFAULT_CPU_CORE=1 local DEFAULT_CPU_UTIL="10-20" local DEFAULT_MEM_UTIL=20 local DEFAULT_SPEEDTEST_INTERVAL=120 - # 사용자에게 CPU 코어 수와 점유율 백분율을 입력하라는 메시지를 표시하고 입력 한 경우 기본값을 사용하십시오. - read -e -p "CPU 코어 수를 입력하십시오 [기본값 :$DEFAULT_CPU_CORE]: " cpu_core + # 사용자에게 CPU 코어 수와 점유율을 입력하라는 메시지를 표시합니다. 사용자가 Enter 키를 누르면 기본값이 사용됩니다. + read -e -p "CPU 코어 수를 입력하십시오.[기본값:$DEFAULT_CPU_CORE]: " cpu_core local cpu_core=${cpu_core:-$DEFAULT_CPU_CORE} - read -e -p "CPU 사용 백분율 범위 (예 : 10-20) [기본값 :$DEFAULT_CPU_UTIL]: " cpu_util + read -e -p "CPU 사용량 백분율 범위(예: 10-20)를 입력하십시오. [기본값:$DEFAULT_CPU_UTIL]: " cpu_util local cpu_util=${cpu_util:-$DEFAULT_CPU_UTIL} - read -e -p "메모리 사용 백분율을 입력하십시오 [기본값 :$DEFAULT_MEM_UTIL]: " mem_util + read -e -p "메모리 사용량 비율을 입력하십시오.[기본값:$DEFAULT_MEM_UTIL]: " mem_util local mem_util=${mem_util:-$DEFAULT_MEM_UTIL} - read -e -p "스피드 테스트 간격 시간 (초)을 입력하십시오 [기본값 :$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval + read -e -p "속도 테스트 간격 시간(초)을 입력하십시오. [기본값:$DEFAULT_SPEEDTEST_INTERVAL]: " speedtest_interval local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} - # 도커 컨테이너를 실행하십시오 - docker run -itd --name=lookbusy --restart=always \ + # Docker 컨테이너 실행 + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ @@ -7314,7 +8124,7 @@ linux_Oracle() { ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -7322,20 +8132,20 @@ linux_Oracle() { clear docker rm -f lookbusy docker rmi fogforest/lookbusy - send_stats "Oracle Cloud는 활성 스크립트를 제거합니다" + send_stats "Oracle Cloud 제거 활성 스크립트" ;; 3) clear - echo "시스템을 다시 설치하십시오" + echo "시스템 재설치" echo "--------------------------------" - echo -e "${gl_hong}알아채다:${gl_bai}다시 설치는 접촉을 잃을 위험이 있으며 걱정하는 사람들은 그것을주의해서 사용해야합니다. 재설치는 15 분이 걸릴 것으로 예상됩니다. 데이터를 미리 백업하십시오." - read -e -p "계속할거야? (Y/N) :" choice + echo -e "${gl_hong}알아채다:${gl_bai}재설치 시 연결이 끊어질 수 있으니 걱정되시는 분들은 주의해서 사용해주세요. 재설치에는 약 15분 정도 소요될 예정이오니, 사전에 데이터를 백업해 주시기 바랍니다." + read -e -p "계속하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) while true; do - read -e -p "다시 설치할 시스템을 선택하십시오 : 1. Debian12 | 2. Ubuntu20.04 :" sys_choice + read -e -p "다시 설치하려는 시스템을 선택하십시오: 1. Debian12 | 2. 우분투20.04:" sys_choice case "$sys_choice" in 1) @@ -7347,28 +8157,29 @@ linux_Oracle() { break # 结束循环 ;; *) - echo "유효하지 않은 선택, 다시 입력하십시오." + echo "선택이 잘못되었습니다. 다시 입력해 주세요." ;; esac done - read -e -p "다시 설치 한 비밀번호를 입력하십시오." vpspasswd + read -e -p "재설치 후 비밀번호를 입력해주세요:" vpspasswd install wget bash <(wget --no-check-certificate -qO- "${gh_proxy}raw.githubusercontent.com/MoeClub/Note/master/InstallNET.sh") $xitong -v 64 -p $vpspasswd -port 22 - send_stats "Oracle Cloud 회복 시스템 스크립트" + send_stats "Oracle Cloud 재설치 시스템 스크립트" ;; [Nn]) echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; 4) clear - echo "이 기능은 개발 단계에 있으므로 계속 지켜봐 주시기 바랍니다!" + send_stats "R 형사 시작 스크립트" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7378,15 +8189,15 @@ linux_Oracle() { 6) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "이 기능은 마스터 JHB가 제공합니다." - send_stats "IPv6 수정" + echo "이 기능은 jhb에서 제공합니다. 감사합니다!" + send_stats "IPv6 수리" ;; 0) kejilion ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -7398,6 +8209,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7407,7 +8221,7 @@ docker_tato() { if command -v docker &> /dev/null; then echo -e "${gl_kjlan}------------------------" - echo -e "${gl_lv}환경이 설치되었습니다${gl_bai}컨테이너:${gl_lv}$container_count${gl_bai}거울:${gl_lv}$image_count${gl_bai}회로망:${gl_lv}$network_count${gl_bai}연타:${gl_lv}$volume_count${gl_bai}" + echo -e "${gl_lv}환경이 설치되었습니다.${gl_bai}컨테이너:${gl_lv}$container_count${gl_bai}거울:${gl_lv}$image_count${gl_bai}회로망:${gl_lv}$network_count${gl_bai}연타:${gl_lv}$volume_count${gl_bai}" fi } @@ -7415,20 +8229,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}환경이 설치됩니다${gl_bai} $output $db_output" + echo -e "${gl_lv}환경이 설치되었습니다${gl_bai}대지:$output데이터 베이스:$db_output" fi fi @@ -7456,31 +8270,31 @@ linux_ldnmp() { while true; do clear - # send_stats "ldnmp 웹 사이트 빌딩" - echo -e "${gl_huang}LDNMP 웹 사이트 구축" + # send_stats "LDNMP 웹사이트 구축" + echo -e "${gl_huang}LDNMP 웹사이트 구축" ldnmp_tato echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}1. ${gl_bai}LDNMP 환경을 설치하십시오${gl_huang}★${gl_bai} ${gl_huang}2. ${gl_bai}WordPress를 설치하십시오${gl_huang}★${gl_bai}" - echo -e "${gl_huang}3. ${gl_bai}Discuz 포럼을 설치하십시오${gl_huang}4. ${gl_bai}Kadao 클라우드 데스크탑을 설치하십시오" - echo -e "${gl_huang}5. ${gl_bai}Apple CMS 영화 및 텔레비전 방송국을 설치하십시오${gl_huang}6. ${gl_bai}유니콘 디지털 카드 네트워크를 설치하십시오" - echo -e "${gl_huang}7. ${gl_bai}Flarum Forum 웹 사이트를 설치하십시오${gl_huang}8. ${gl_bai}Typecho Lightweight 블로그 웹 사이트를 설치하십시오" - echo -e "${gl_huang}9. ${gl_bai}LinkStack 공유 링크 플랫폼을 설치하십시오${gl_huang}20. ${gl_bai}동적 사이트를 사용자 정의합니다" + echo -e "${gl_huang}1. ${gl_bai}LDNMP 환경 설치${gl_huang}★${gl_bai} ${gl_huang}2. ${gl_bai}워드프레스 설치${gl_huang}★${gl_bai}" + echo -e "${gl_huang}3. ${gl_bai}Discuz 포럼 설치${gl_huang}4. ${gl_bai}Kedao 클라우드 데스크탑 설치" + echo -e "${gl_huang}5. ${gl_bai}Apple CMS 영화 및 TV 스테이션 설치${gl_huang}6. ${gl_bai}Unicorn 디지털 카드 네트워크 설치" + echo -e "${gl_huang}7. ${gl_bai}flarum 포럼 웹사이트 설치${gl_huang}8. ${gl_bai}typecho 경량 블로그 웹사이트 설치" + echo -e "${gl_huang}9. ${gl_bai}LinkStack 공유 링크 플랫폼 설치${gl_huang}20. ${gl_bai}맞춤 동적 사이트" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}21. ${gl_bai}nginx 만 설치하십시오${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}사이트 리디렉션" - echo -e "${gl_huang}23. ${gl_bai}사이트 리버스 프록시 -IP+포트${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}사이트 리버스 프록시 - 도메인 이름" - echo -e "${gl_huang}25. ${gl_bai}Bitwarden 비밀번호 관리 플랫폼을 설치하십시오${gl_huang}26. ${gl_bai}후광 블로그 웹 사이트를 설치하십시오" - echo -e "${gl_huang}27. ${gl_bai}AI 페인팅 프롬프트 워드 생성기를 설치하십시오${gl_huang}28. ${gl_bai}사이트 리버스 프록시로드 밸런싱" - echo -e "${gl_huang}30. ${gl_bai}정적 사이트를 사용자 정의합니다" + echo -e "${gl_huang}21. ${gl_bai}nginx만 설치하세요${gl_huang}★${gl_bai} ${gl_huang}22. ${gl_bai}사이트 리디렉션" + echo -e "${gl_huang}23. ${gl_bai}사이트 역방향 프록시-IP+포트${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}사이트 역방향 프록시 도메인 이름" + echo -e "${gl_huang}25. ${gl_bai}Bitwarden 비밀번호 관리 플랫폼 설치${gl_huang}26. ${gl_bai}Halo 블로그 사이트 설치" + echo -e "${gl_huang}27. ${gl_bai}AI 그림 프롬프트 단어 생성기 설치${gl_huang}28. ${gl_bai}사이트 역방향 프록시-로드 밸런싱" + echo -e "${gl_huang}29. ${gl_bai}스트림 4계층 프록시 전달${gl_huang}30. ${gl_bai}사용자 정의 정적 사이트" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}31. ${gl_bai}사이트 데이터 관리${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}전체 사이트 데이터를 백업합니다" - echo -e "${gl_huang}33. ${gl_bai}시간이 지정된 원격 백업${gl_huang}34. ${gl_bai}전체 사이트 데이터를 복원하십시오" + echo -e "${gl_huang}31. ${gl_bai}사이트 데이터 관리${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}사이트 전체 데이터 백업" + echo -e "${gl_huang}33. ${gl_bai}예약된 원격 백업${gl_huang}34. ${gl_bai}전체 사이트 데이터 복원" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}35. ${gl_bai}LDNMP 환경을 보호하십시오${gl_huang}36. ${gl_bai}LDNMP 환경을 최적화하십시오" - echo -e "${gl_huang}37. ${gl_bai}LDNMP 환경을 업데이트하십시오${gl_huang}38. ${gl_bai}LDNMP 환경을 제거하십시오" + echo -e "${gl_huang}35. ${gl_bai}LDNMP 환경 보호${gl_huang}36. ${gl_bai}LDNMP 환경 최적화" + echo -e "${gl_huang}37. ${gl_bai}LDNMP 환경 업데이트${gl_huang}38. ${gl_bai}LDNMP 환경 제거" echo -e "${gl_huang}------------------------" - echo -e "${gl_huang}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_huang}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_huang}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in @@ -7494,25 +8308,30 @@ linux_ldnmp() { 3) clear - # Discuz 포럼 - webname="Discuz论坛" + # 토론 포럼 + webname="토론 포럼" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7520,11 +8339,11 @@ linux_ldnmp() { ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "테이블 접두사 : discuz_" + echo "테이블 접두사: discuz_" ;; @@ -7532,18 +8351,21 @@ linux_ldnmp() { 4) clear # Kedao 클라우드 데스크탑 - webname="可道云桌面" + webname="Kedao 클라우드 데스크탑" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7556,29 +8378,33 @@ linux_ldnmp() { restart_ldnmp ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "데이터베이스 이름 :$dbname" - echo "Redis 호스트 : Redis" + echo "데이터베이스 이름:$dbname" + echo "레디스 호스트: 레디스" ;; 5) clear - # Apple CMS - webname="苹果CMS" + # AppleCMS + webname="AppleCMS" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7595,33 +8421,37 @@ linux_ldnmp() { ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 포트 : 3306" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 포트: 3306" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "데이터베이스 접두사 : MAC_" + echo "데이터베이스 접두사: mac_" echo "------------------------" - echo "설치가 성공한 후 배경 주소에 로그인하십시오." + echo "설치가 성공적으로 완료되면 백엔드 주소로 로그인하세요." echo "https://$yuming/vip.php" ;; 6) clear - # 한 다리 카운팅 카드 - webname="独脚数卡" + # 한쪽다리 숫자카드 + webname="한쪽다리 숫자카드" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7633,43 +8463,46 @@ linux_ldnmp() { ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 포트 : 3306" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 포트: 3306" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" echo "" - echo "Redis 주소 : Redis" - echo "Redis Password : 기본적으로 채워지지 않습니다" - echo "Redis Port : 6379" + echo "레디스 주소 : 레디스" + echo "redis 비밀번호: 기본적으로 입력되지 않음" + echo "레디스 포트: 6379" echo "" - echo "웹 사이트 URL : https : //$yuming" - echo "백그라운드 로그인 경로 : /admin" + echo "웹사이트 URL: https://$yuming" + echo "백엔드 로그인 경로: /admin" echo "------------------------" - echo "사용자 이름 : 관리자" - echo "비밀번호 : 관리자" + echo "사용자 이름: 관리자" + echo "비밀번호: 관리자" echo "------------------------" - echo "로그인 할 때 오른쪽 상단에 빨간색 Error0이 나타나면 다음 명령을 사용하십시오." - echo "나는 또한 유니콘 번호 카드가 너무 귀찮다는 것에 대해 매우 화가 났으며 그러한 문제가있을 것입니다!" + echo "로그인 시 오른쪽 상단에 빨간색 error0이 나타나는 경우, 다음 명령어를 사용하시기 바랍니다." + echo "유니콘 숫자카드가 왜 이렇게 귀찮고 이런 문제가 있는지에 대해서도 너무 화가 납니다!" echo "sed -i 's/ADMIN_HTTPS=false/ADMIN_HTTPS=true/g' /home/web/html/$yuming/dujiaoka/.env" ;; 7) clear - # Flarum 포럼 - webname="flarum论坛" + # 플라럼 포럼 + webname="플라럼 포럼" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7690,19 +8523,23 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "테이블 접두사 : flarum_" - echo "관리자 정보는 직접 설정됩니다" + echo "테이블 접두사: flarum_" + echo "관리자 정보는 직접 설정 가능" ;; @@ -7711,16 +8548,20 @@ linux_ldnmp() { # typecho webname="typecho" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7735,11 +8576,11 @@ linux_ldnmp() { clear ldnmp_web_on - echo "데이터베이스 접두사 : typecho_" - echo "데이터베이스 주소 : MySQL" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 접두사: typecho_" + echo "데이터베이스 주소: mysql" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "데이터베이스 이름 :$dbname" + echo "데이터베이스 이름:$dbname" ;; @@ -7749,17 +8590,20 @@ linux_ldnmp() { # LinkStack webname="LinkStack" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7774,27 +8618,30 @@ linux_ldnmp() { clear ldnmp_web_on - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 포트 : 3306" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 포트: 3306" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" ;; 20) clear - webname="PHP动态站点" + webname="PHP 동적 사이트" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7802,10 +8649,10 @@ linux_ldnmp() { cd $yuming clear - echo -e "[${gl_huang}1/6${gl_bai}] PHP 소스 코드를 업로드하십시오" + echo -e "[${gl_huang}1/6${gl_bai}] PHP 소스 코드 업로드" echo "-------------" - echo "현재 Zip-Format 소스 코드 패키지 만 허용됩니다. 소스 코드 패키지를/home/web/html에 넣으십시오.${yuming}디렉토리에서" - read -e -p "다운로드 링크를 입력하여 소스 코드 패키지를 원격으로 다운로드 할 수도 있습니다. 원격 다운로드를 건너 뛰려면 Enter를 직접 누르십시오." url_download + echo "현재는 zip 형식의 소스 코드 패키지만 업로드할 수 있습니다. 소스 코드 패키지를 /home/web/html/에 넣어주세요.${yuming}디렉토리 아래" + read -e -p "다운로드 링크를 입력하여 소스 코드 패키지를 원격으로 다운로드할 수도 있습니다. 원격 다운로드를 건너뛰려면 Enter를 직접 누르세요." url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -7815,20 +8662,20 @@ linux_ldnmp() { rm -f $(ls -t *.zip | head -n 1) clear - echo -e "[${gl_huang}2/6${gl_bai}] index.php가있는 경로" + echo -e "[${gl_huang}2/6${gl_bai}] index.php가 위치한 경로" echo "-------------" # find "$(realpath .)" -name "index.php" -print find "$(realpath .)" -name "index.php" -print | xargs -I {} dirname {} - read -e -p "(/home/web/html/와 유사한 Index.php의 경로를 입력하십시오.$yuming/wordpress/): " index_lujing + read -e -p "(/home/web/html/과 유사하게 index.php 경로를 입력하세요.$yuming/wordpress/): " index_lujing sed -i "s#root /var/www/html/$yuming/#root $index_lujing#g" /home/web/conf.d/$yuming.conf sed -i "s#/home/web/#/var/www/#g" /home/web/conf.d/$yuming.conf clear - echo -e "[${gl_huang}3/6${gl_bai}] PHP 버전을 선택하십시오" + echo -e "[${gl_huang}3/6${gl_bai}] PHP 버전을 선택해주세요." echo "-------------" - read -e -p "1. PHP의 최신 버전 | 2. PHP7.4 :" pho_v + read -e -p "1. PHP 최신 버전 | 2.php7.4:" pho_v case "$pho_v" in 1) sed -i "s#php:9000#php:9000#g" /home/web/conf.d/$yuming.conf @@ -7839,15 +8686,15 @@ linux_ldnmp() { local PHP_Version="php74" ;; *) - echo "유효하지 않은 선택, 다시 입력하십시오." + echo "선택이 잘못되었습니다. 다시 입력해 주세요." ;; esac clear - echo -e "[${gl_huang}4/6${gl_bai}] 지정된 확장자를 설치하십시오" + echo -e "[${gl_huang}4/6${gl_bai}] 지정된 확장 설치" echo "-------------" - echo "설치된 확장" + echo "설치된 확장 프로그램" docker exec php php -m read -e -p "$(echo -e "输入需要安装的扩展名称,如 ${gl_huang}SourceGuardian imap ftp${gl_bai} 等等。直接回车将跳过安装 : ")" php_extensions @@ -7859,7 +8706,7 @@ linux_ldnmp() { clear echo -e "[${gl_huang}5/6${gl_bai}] 사이트 구성 편집" echo "-------------" - echo "계속하려면 모든 키를 누르면 의사 정적 내용 등과 같은 사이트 구성을 자세히 설정할 수 있습니다." + echo "계속하려면 아무 키나 누르세요. 의사정적 콘텐츠 등 사이트 구성을 세부적으로 설정할 수 있습니다." read -n 1 -s -r -p "" install nano nano /home/web/conf.d/$yuming.conf @@ -7868,14 +8715,14 @@ linux_ldnmp() { clear echo -e "[${gl_huang}6/6${gl_bai}] 데이터베이스 관리" echo "-------------" - read -e -p "1. 새 사이트를 구축합니다. 2. 이전 사이트를 작성하고 데이터베이스 백업이 있습니다." use_db + read -e -p "1. 새 사이트를 구축합니다. 2. 이전 사이트를 구축하고 데이터베이스 백업을 가지고 있습니다." use_db case $use_db in 1) echo ;; 2) - echo "데이터베이스 백업은 .gz-end 압축 패키지 여야합니다. Pagoda/1Panel의 백업 데이터 가져 오기를 지원하려면/홈/디렉토리에 넣으십시오." - read -e -p "다운로드 링크를 입력하여 백업 데이터를 원격으로 다운로드 할 수도 있습니다. Enter가 직접 누르면 원격 다운로드를 건너 뜁니다." url_download_db + echo "데이터베이스 백업은 .gz로 끝나는 압축 패키지여야 합니다. Pagoda/1panel 백업 데이터 가져오기를 지원하려면 /home/ 디렉토리에 넣으십시오." + read -e -p "다운로드 링크를 입력하여 원격으로 백업 데이터를 다운로드할 수도 있습니다. 원격 다운로드를 건너뛰려면 Enter를 직접 누르세요." url_download_db cd /home/ if [ -n "$url_download_db" ]; then @@ -7885,10 +8732,10 @@ linux_ldnmp() { latest_sql=$(ls -t *.sql | head -n 1) dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname < "/home/$latest_sql" - echo "데이터베이스 가져 오기 테이블 데이터" + echo "데이터베이스에서 가져온 테이블 데이터" docker exec -i mysql mysql -u root -p"$dbrootpasswd" -e "USE $dbname; SHOW TABLES;" rm -f *.sql - echo "데이터베이스 가져 오기가 완료되었습니다" + echo "데이터베이스 가져오기 완료" ;; *) echo @@ -7900,12 +8747,12 @@ linux_ldnmp() { restart_ldnmp ldnmp_web_on prefix="web$(shuf -i 10-99 -n 1)_" - echo "데이터베이스 주소 : MySQL" - echo "데이터베이스 이름 :$dbname" - echo "사용자 이름 :$dbuse" + echo "데이터베이스 주소: mysql" + echo "데이터베이스 이름:$dbname" + echo "사용자 이름:$dbuse" echo "비밀번호:$dbusepasswd" - echo "테이블 접두사 :$prefix" - echo "관리자 로그인 정보는 직접 설정됩니다" + echo "테이블 접두사:$prefix" + echo "관리자 로그인 정보는 직접 설정합니다." ;; @@ -7917,18 +8764,21 @@ linux_ldnmp() { 22) clear - webname="站点重定向" + webname="사이트 리디렉션" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming - read -e -p "점프 도메인 이름을 입력하십시오 :" reverseproxy + read -e -p "리디렉션 도메인 이름을 입력하세요." reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7943,7 +8793,7 @@ linux_ldnmp() { find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ 포트는 서비스에 액세스하는 것이 차단되었습니다" + echo "IP+포트가 서비스 접근을 차단했습니다." else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -7953,19 +8803,21 @@ linux_ldnmp() { 24) clear - webname="反向代理-域名" + webname="역방향 프록시 도메인 이름" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming - echo -e "도메인 이름 형식 :${gl_huang}google.com${gl_bai}" - read -e -p "반세기 도메인 이름을 입력하십시오 :" fandai_yuming + echo -e "도메인 이름 형식:${gl_huang}google.com${gl_bai}" + read -e -p "역방향 프록시 도메인 이름을 입력하세요:" fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7979,22 +8831,19 @@ linux_ldnmp() { clear webname="Bitwarden" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8002,32 +8851,30 @@ linux_ldnmp() { clear webname="halo" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; 27) clear - webname="AI绘画提示词生成器" + webname="AI 그림 프롬프트 단어 생성기" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8050,19 +8897,25 @@ linux_ldnmp() { ;; + 29) + stream_panel + ;; + 30) clear - webname="静态站点" + webname="정적 사이트" send_stats "설치하다$webname" - echo "배포를 시작하십시오$webname" + echo "배포 시작$webname" add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8071,10 +8924,10 @@ linux_ldnmp() { clear - echo -e "[${gl_huang}1/2${gl_bai}] 정적 소스 코드를 업로드하십시오" + echo -e "[${gl_huang}1/2${gl_bai}] 정적 소스 코드 업로드" echo "-------------" - echo "현재 Zip-Format 소스 코드 패키지 만 허용됩니다. 소스 코드 패키지를/home/web/html에 넣으십시오.${yuming}디렉토리에서" - read -e -p "다운로드 링크를 입력하여 소스 코드 패키지를 원격으로 다운로드 할 수도 있습니다. 원격 다운로드를 건너 뛰려면 Enter를 직접 누르십시오." url_download + echo "현재는 zip 형식의 소스 코드 패키지만 업로드할 수 있습니다. 소스 코드 패키지를 /home/web/html/에 넣어주세요.${yuming}디렉토리 아래" + read -e -p "다운로드 링크를 입력하여 소스 코드 패키지를 원격으로 다운로드할 수도 있습니다. 원격 다운로드를 건너뛰려면 Enter를 직접 누르세요." url_download if [ -n "$url_download" ]; then wget "$url_download" @@ -8084,12 +8937,12 @@ linux_ldnmp() { rm -f $(ls -t *.zip | head -n 1) clear - echo -e "[${gl_huang}2/2${gl_bai}] index.html이있는 경로" + echo -e "[${gl_huang}2/2${gl_bai}] index.html이 위치한 경로" echo "-------------" # find "$(realpath .)" -name "index.html" -print find "$(realpath .)" -name "index.html" -print | xargs -I {} dirname {} - read -e -p "(/home/web/html/와 유사한 index.html로가는 경로를 입력하십시오.$yuming/index/): " index_lujing + read -e -p "(/home/web/html/과 유사하게 index.html 경로를 입력하세요.$yuming/index/): " index_lujing sed -i "s#root /var/www/html/$yuming/#root $index_lujing#g" /home/web/conf.d/$yuming.conf sed -i "s#/home/web/#/var/www/#g" /home/web/conf.d/$yuming.conf @@ -8117,28 +8970,30 @@ linux_ldnmp() { send_stats "LDNMP 환경 백업" local backup_filename="web_$(date +"%Y%m%d%H%M%S").tar.gz" - echo -e "${gl_huang}백업$backup_filename ...${gl_bai}" + echo -e "${gl_huang}백업 중$backup_filename ...${gl_bai}" cd /home/ && tar czvf "$backup_filename" web while true; do clear - echo "백업 파일이 작성되었습니다 : /home /$backup_filename" - read -e -p "백업 데이터를 원격 서버로 전송 하시겠습니까? (Y/N) :" choice + echo "생성된 백업 파일: /home/$backup_filename" + read -e -p "백업 데이터를 원격 서버로 전송하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) - read -e -p "원격 서버 IP를 입력하십시오 :" remote_ip + read -e -p "원격 서버 IP를 입력하세요:" remote_ip + read -e -p "대상 서버 SSH 포트 [기본값 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then - echo "오류 : 원격 서버 IP를 입력하십시오." + echo "오류: 원격 서버 IP를 입력하세요." continue fi local latest_tar=$(ls -t /home/*.tar.gz | head -1) if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" - echo "파일은 원격 서버 홈 디렉토리로 전송되었습니다." + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + echo "파일이 원격 서버 홈 디렉터리로 전송되었습니다." else - echo "전송할 파일은 찾을 수 없었습니다." + echo "전송할 파일을 찾을 수 없습니다." fi break ;; @@ -8146,7 +9001,7 @@ linux_ldnmp() { break ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac done @@ -8154,9 +9009,9 @@ linux_ldnmp() { 33) clear - send_stats "시간이 지정된 원격 백업" - read -e -p "원격 서버 IP를 입력하십시오." useip - read -e -p "원격 서버 비밀번호를 입력하십시오." usepasswd + send_stats "예약된 원격 백업" + read -e -p "원격 서버 IP를 입력하세요." useip + read -e -p "원격 서버 비밀번호를 입력하세요:" usepasswd cd ~ wget -O ${useip}_beifen.sh ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/beifen.sh > /dev/null 2>&1 @@ -8166,18 +9021,18 @@ linux_ldnmp() { sed -i "s/123456/$usepasswd/g" ${useip}_beifen.sh echo "------------------------" - echo "1. 주간 백업 2. 매일 백업" - read -e -p "선택을 입력하십시오 :" dingshi + echo "1. 주간 백업 2. 일일 백업" + read -e -p "선택사항을 입력하세요:" dingshi case $dingshi in 1) check_crontab_installed - read -e -p "주간 백업의 요일을 선택하십시오 (0-6, 0은 일요일을 나타냅니다) :" weekday + read -e -p "주간 백업 요일을 선택합니다(0-6, 0은 일요일을 나타냄)." weekday (crontab -l ; echo "0 0 * * $weekday ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; 2) check_crontab_installed - read -e -p "매일 백업 시간을 선택하십시오 (시간, 0-23) :" hour + read -e -p "일일 백업 시간 선택(시간, 0-23):" hour (crontab -l ; echo "0 $hour * * * ./${useip}_beifen.sh") | crontab - > /dev/null 2>&1 ;; *) @@ -8196,14 +9051,14 @@ linux_ldnmp() { echo "-------------------------" ls -lt /home/*.gz | awk '{print $NF}' echo "" - read -e -p "최신 백업을 복원하려면 입력하고 백업 파일 이름을 입력하여 지정된 백업을 복원하고 0을 입력하려면 다음을 종료하십시오." filename + read -e -p "최신 백업을 복원하려면 Enter 키를 누르고, 지정된 백업을 복원하려면 백업 파일 이름을 입력하고, 종료하려면 0을 입력하세요." filename if [ "$filename" == "0" ]; then break_end linux_ldnmp fi - # 사용자가 파일 이름을 입력하지 않으면 최신 압축 패키지를 사용하십시오. + # 사용자가 파일명을 입력하지 않으면 최신 압축 패키지가 사용됩니다. if [ -z "$filename" ]; then local filename=$(ls -t /home/*.tar.gz | head -1) fi @@ -8213,16 +9068,15 @@ linux_ldnmp() { docker compose down > /dev/null 2>&1 rm -rf /home/web > /dev/null 2>&1 - echo -e "${gl_huang}감압이 수행되고 있습니다$filename ...${gl_bai}" + echo -e "${gl_huang}압축 해제 중$filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot install_ldnmp else - echo "압축 패키지가 발견되지 않았습니다." + echo "압축된 패키지를 찾을 수 없습니다." fi ;; @@ -8240,11 +9094,11 @@ linux_ldnmp() { root_use while true; do clear - send_stats "LDNMP 환경을 업데이트하십시오" - echo "LDNMP 환경을 업데이트하십시오" + send_stats "LDNMP 환경 업데이트" + echo "LDNMP 환경 업데이트" echo "------------------------" ldnmp_v - echo "구성 요소의 새 버전을 발견하십시오" + echo "새 버전의 구성 요소가 발견되었습니다." echo "------------------------" check_docker_image_update nginx if [ -n "$update_status" ]; then @@ -8264,13 +9118,13 @@ linux_ldnmp() { fi echo "------------------------" echo - echo "1. Nginx 업데이트 2. MySQL 업데이트 3. PHP 업데이트 4. Redis 업데이트" + echo "1. nginx 업데이트 2. mysql 업데이트 3. PHP 업데이트 4. redis 업데이트" echo "------------------------" - echo "5. 전체 환경을 업데이트하십시오" + echo "5. 전체 환경 업데이트" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) nginx_upgrade @@ -8279,7 +9133,7 @@ linux_ldnmp() { 2) local ldnmp_pods="mysql" - read -e -p "입력하십시오${ldnmp_pods}버전 번호 (예 : 8.0 8.3 8.4 9.0) (최신 버전을 얻으려면 입력) :" version + read -e -p "입력해주세요${ldnmp_pods}버전 번호(예: 8.0 8.3 8.4 9.0)(최신 버전을 얻으려면 Enter 키를 누르세요):" version local version=${version:-latest} cd /home/web/ @@ -8296,7 +9150,7 @@ linux_ldnmp() { ;; 3) local ldnmp_pods="php" - read -e -p "입력하십시오${ldnmp_pods}버전 번호 (예 : 7.4 8.0 8.1 8.2 8.3) (최신 버전을 얻으려면 입력) :" version + read -e -p "입력해주세요${ldnmp_pods}버전 번호(예: 7.4 8.0 8.1 8.2 8.3)(최신 버전을 얻으려면 Enter 키를 누르세요):" version local version=${version:-8.3} cd /home/web/ cp /home/web/docker-compose.yml /home/web/docker-compose1.yml @@ -8340,7 +9194,6 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis send_stats "고쳐 쓰다$ldnmp_pods" echo "고쳐 쓰다${ldnmp_pods}마치다" @@ -8349,11 +9202,10 @@ linux_ldnmp() { read -e -p "$(echo -e "${gl_huang}提示: ${gl_bai}长时间不更新环境的用户,请慎重更新LDNMP环境,会有数据库更新失败的风险。确定更新LDNMP环境吗?(Y/N): ")" choice case "$choice" in [Yy]) - send_stats "LDNMP 환경을 완전히 업데이트하십시오" + send_stats "LDNMP 환경 전체 업데이트" cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8375,7 +9227,7 @@ linux_ldnmp() { 38) root_use - send_stats "LDNMP 환경을 제거하십시오" + send_stats "LDNMP 환경 제거" read -e -p "$(echo -e "${gl_hong}强烈建议:${gl_bai}先备份全部网站数据,再卸载LDNMP环境。确定删除所有网站数据吗?(Y/N): ")" choice case "$choice" in [Yy]) @@ -8389,7 +9241,7 @@ linux_ldnmp() { ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -8399,7 +9251,7 @@ linux_ldnmp() { ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" esac break_end @@ -8411,2264 +9263,3901 @@ linux_ldnmp() { linux_panel() { - while true; do +local sub_choice="$1" + +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi + +while true; do + + if [ -z "$sub_choice" ]; then clear - # Send_stats "앱 시장" - echo -e "응용 프로그램 시장" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}Baota 패널의 공식 버전${gl_kjlan}2. ${gl_bai}Aapanel International Edition" - echo -e "${gl_kjlan}3. ${gl_bai}1 파넬 신세대 관리 패널${gl_kjlan}4. ${gl_bai}nginxproxymanager 시각적 패널" - echo -e "${gl_kjlan}5. ${gl_bai}OpenList 멀티 스토어 파일 목록 프로그램${gl_kjlan}6. ${gl_bai}우분투 원격 데스크탑 웹 에디션" - echo -e "${gl_kjlan}7. ${gl_bai}Nezha 프로브 VPS 모니터링 패널${gl_kjlan}8. ${gl_bai}QB 오프라인 BT 자기 다운로드 패널" - echo -e "${gl_kjlan}9. ${gl_bai}Poste.io 메일 서버 프로그램${gl_kjlan}10. ${gl_bai}Rocketchat 멀티 플레이어 온라인 채팅 시스템" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}Zendao 프로젝트 관리 소프트웨어${gl_kjlan}12. ${gl_bai}Qinglong 패널 시간 작업 관리 플랫폼" - echo -e "${gl_kjlan}13. ${gl_bai}CloudReve 네트워크 디스크${gl_huang}★${gl_bai} ${gl_kjlan}14. ${gl_bai}간단한 그림 침대 그림 관리 프로그램" - echo -e "${gl_kjlan}15. ${gl_bai}EMBY 멀티미디어 관리 시스템${gl_kjlan}16. ${gl_bai}스피드 테스트 속도 테스트 패널" - echo -e "${gl_kjlan}17. ${gl_bai}Adguardhome Adware${gl_kjlan}18. ${gl_bai}Office Office Online Office Office" - echo -e "${gl_kjlan}19. ${gl_bai}썬더 풀 WAF 방화벽 패널${gl_kjlan}20. ${gl_bai}Portainer 컨테이너 관리 패널" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}VSCODE 웹 버전${gl_kjlan}22. ${gl_bai}Uptimekuma 모니터링 도구" - echo -e "${gl_kjlan}23. ${gl_bai}메모 웹 페이지 메모${gl_kjlan}24. ${gl_bai}WebTop 원격 데스크탑 웹 에디션${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}25. ${gl_bai}NextCloud 네트워크 디스크${gl_kjlan}26. ${gl_bai}QD-Today 타이밍 작업 관리 프레임 워크" - echo -e "${gl_kjlan}27. ${gl_bai}도크 컨테이너 스택 관리 패널${gl_kjlan}28. ${gl_bai}Librespeed 속도 테스트 도구" - echo -e "${gl_kjlan}29. ${gl_bai}searxng 집계 검색 사이트${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}Photoprism 개인 앨범 시스템" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}Stirlingpdf 도구 컬렉션${gl_kjlan}32. ${gl_bai}Drawio 무료 온라인 차트 소프트웨어${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}썬 패널 탐색 패널${gl_kjlan}34. ${gl_bai}Pingvin-Share 파일 공유 플랫폼" - echo -e "${gl_kjlan}35. ${gl_bai}미니멀리스트 친구들${gl_kjlan}36. ${gl_bai}LobeChatai 채팅 집계 웹 사이트" - echo -e "${gl_kjlan}37. ${gl_bai}MYIP 도구 상자${gl_huang}★${gl_bai} ${gl_kjlan}38. ${gl_bai}Xiaoya Alist 가족 버킷" - echo -e "${gl_kjlan}39. ${gl_bai}Bilililive 라이브 방송 녹음 도구${gl_kjlan}40. ${gl_bai}Websh 웹 버전 SSH 연결 도구" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}마우스 관리 패널${gl_kjlan}42. ${gl_bai}Nexte 원격 연결 도구" - echo -e "${gl_kjlan}43. ${gl_bai}Rustdesk 원격 책상 (서버)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${gl_bai}Rustdesk 원격 책상 (릴레이)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}45. ${gl_bai}도커 가속 스테이션${gl_kjlan}46. ${gl_bai}Github Acceleration Station${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}47. ${gl_bai}프로 메테우스 모니터링${gl_kjlan}48. ${gl_bai}프로 메테우스 (호스트 모니터링)" - echo -e "${gl_kjlan}49. ${gl_bai}Prometheus (컨테이너 모니터링)${gl_kjlan}50. ${gl_bai}보충 모니터링 도구" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}51. ${gl_bai}PVE 치킨 패널${gl_kjlan}52. ${gl_bai}DPANEL 컨테이너 관리 패널" - echo -e "${gl_kjlan}53. ${gl_bai}llama3 채팅 AI 모델${gl_kjlan}54. ${gl_bai}AMH 호스트 웹 사이트 빌딩 관리 패널" - echo -e "${gl_kjlan}55. ${gl_bai}FRP 인트라넷 침투 (서버 측)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${gl_bai}FRP 인트라넷 침투 (클라이언트)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}57. ${gl_bai}DeepSeek 채팅 AI 큰 모델${gl_kjlan}58. ${gl_bai}Dify Big Model 지식 기반${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}59. ${gl_bai}Newapi 큰 모델 자산 관리${gl_kjlan}60. ${gl_bai}점프 서버 오픈 소스 요새 기계" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}61. ${gl_bai}온라인 번역 서버${gl_kjlan}62. ${gl_bai}래그 플로 큰 모델 지식 기반" - echo -e "${gl_kjlan}63. ${gl_bai}OpenWebui 자체 호스팅 AI 플랫폼${gl_huang}★${gl_bai} ${gl_kjlan}64. ${gl_bai}it-tools 도구 상자" - echo -e "${gl_kjlan}65. ${gl_bai}N8N 자동화 워크 플로 플랫폼${gl_huang}★${gl_bai} ${gl_kjlan}66. ${gl_bai}YT-DLP 비디오 다운로드 도구" - echo -e "${gl_kjlan}67. ${gl_bai}DDNS-GO 동적 DNS 관리 도구${gl_huang}★${gl_bai} ${gl_kjlan}68. ${gl_bai}AllInsSL 인증서 관리 플랫폼" - echo -e "${gl_kjlan}69. ${gl_bai}sftpgo 파일 전송 도구${gl_kjlan}70. ${gl_bai}Astrbot 채팅 로봇 프레임 워크" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}71. ${gl_bai}Navidrome 개인 음악 서버${gl_kjlan}72. ${gl_bai}Bitwarden 비밀번호 관리자${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}73. ${gl_bai}Libretv 개인 영화 및 텔레비전${gl_kjlan}74. ${gl_bai}Moontv 개인 영화" - echo -e "${gl_kjlan}75. ${gl_bai}멜로디 음악 엘프${gl_kjlan}76. ${gl_bai}온라인 dos 오래된 게임" - echo -e "${gl_kjlan}77. ${gl_bai}천둥 오프라인 다운로드 도구${gl_kjlan}78. ${gl_bai}Pandawiki 지능형 문서 관리 시스템" - echo -e "${gl_kjlan}79. ${gl_bai}Beszel 서버 모니터링" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" - echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + echo -e "응용 시장" + echo -e "${gl_kjlan}-------------------------" - case $sub_choice in - 1) + local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") + + # 루프를 사용하여 색상 설정 + for i in {1..150}; do + if echo "$app_numbers" | grep -q "^$i$"; then + declare "color$i=${gl_lv}" + else + declare "color$i=${gl_bai}" + fi + done + + echo -e "${gl_kjlan}1. ${color1}파고다 패널 공식 버전${gl_kjlan}2. ${color2}aaPanel Pagoda 국제 버전" + echo -e "${gl_kjlan}3. ${color3}1패널 차세대 관리 패널${gl_kjlan}4. ${color4}NginxProxyManager 시각화 패널" + echo -e "${gl_kjlan}5. ${color5}OpenList 다중 저장소 파일 목록 프로그램${gl_kjlan}6. ${color6}Ubuntu 원격 데스크톱 웹 에디션" + echo -e "${gl_kjlan}7. ${color7}나타 프로브 VPS 모니터링 패널${gl_kjlan}8. ${color8}QB 오프라인 BT 자기 다운로드 패널" + echo -e "${gl_kjlan}9. ${color9}Poste.io 메일 서버 프로그램${gl_kjlan}10. ${color10}RocketChat 다자간 온라인 채팅 시스템" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}11. ${color11}ZenTao 프로젝트 관리 소프트웨어${gl_kjlan}12. ${color12}Qinglong 패널 예정된 작업 관리 플랫폼" + echo -e "${gl_kjlan}13. ${color13}Cloudreve 네트워크 디스크${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}간단한 그림 침대 그림 관리 프로그램" + echo -e "${gl_kjlan}15. ${color15}emby 멀티미디어 관리 시스템${gl_kjlan}16. ${color16}Speedtest 속도 테스트 패널" + echo -e "${gl_kjlan}17. ${color17}AdGuardHome은 애드웨어를 제거합니다${gl_kjlan}18. ${color18}onlyoffice온라인 오피스 OFFICE" + echo -e "${gl_kjlan}19. ${color19}Leichi WAF 방화벽 패널${gl_kjlan}20. ${color20}포테이너 컨테이너 관리 패널" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}21. ${color21}VScode 웹 버전${gl_kjlan}22. ${color22}UptimeKuma 모니터링 도구" + echo -e "${gl_kjlan}23. ${color23}메모 웹 메모${gl_kjlan}24. ${color24}Webtop 원격 데스크톱 웹 버전${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}25. ${color25}Nextcloud 네트워크 디스크${gl_kjlan}26. ${color26}QD-오늘 예약된 작업 관리 프레임워크" + echo -e "${gl_kjlan}27. ${color27}Dockge 컨테이너 스택 관리 패널${gl_kjlan}28. ${color28}LibreSpeed ​​​​속도 테스트 도구" + echo -e "${gl_kjlan}29. ${color29}searxng 집계 검색 스테이션${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrism 개인 앨범 시스템" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}31. ${color31}StirlingPDF 도구 모음${gl_kjlan}32. ${color32}drawio 무료 온라인 차트 작성 소프트웨어${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${color33}Sun 패널 탐색 패널${gl_kjlan}34. ${color34}Pingvin-Share 파일 공유 플랫폼" + echo -e "${gl_kjlan}35. ${color35}미니멀리스트 친구들${gl_kjlan}36. ${color36}LobeChatAI 채팅 집계 웹사이트" + echo -e "${gl_kjlan}37. ${color37}MyIP 도구 상자${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}Xiaoya alist 가족 버킷" + echo -e "${gl_kjlan}39. ${color39}Bililive 라이브 방송 녹음 도구${gl_kjlan}40. ${color40}webssh 웹 버전 SSH 연결 도구" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}41. ${color41}마우스 관리 패널${gl_kjlan}42. ${color42}Nexterm 원격 연결 도구" + echo -e "${gl_kjlan}43. ${color43}RustDesk 원격 데스크톱(서버)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk 원격 데스크톱(릴레이)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}45. ${color45}도커 가속 스테이션${gl_kjlan}46. ${color46}GitHub 가속 스테이션${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}47. ${color47}프로메테우스 모니터링${gl_kjlan}48. ${color48}프로메테우스(호스트 모니터링)" + echo -e "${gl_kjlan}49. ${color49}프로메테우스(컨테이너 모니터링)${gl_kjlan}50. ${color50}보충 모니터링 도구" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}51. ${color51}PVE 오픈 병아리 패널${gl_kjlan}52. ${color52}DPanel 컨테이너 관리 패널" + echo -e "${gl_kjlan}53. ${color53}라마3 채팅 AI 대형 모델${gl_kjlan}54. ${color54}AMH 호스트 웹사이트 구축 관리 패널" + echo -e "${gl_kjlan}55. ${color55}FRP 인트라넷 침투(서버)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRP 인트라넷 침투(클라이언트)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}57. ${color57}Deepseek 채팅 AI 대형 모델${gl_kjlan}58. ${color58}대규모 모델 지식 기반 확장${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}59. ${color59}NewAPI 대형 모델 자산 관리${gl_kjlan}60. ${color60}JumpServer 오픈 소스 요새 머신" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}61. ${color61}온라인 번역 서버${gl_kjlan}62. ${color62}RAGFlow 대규모 모델 지식 기반" + echo -e "${gl_kjlan}63. ${color63}OpenWebUI 자체 호스팅 AI 플랫폼${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}it-tools 도구 상자" + echo -e "${gl_kjlan}65. ${color65}n8n 자동화된 워크플로우 플랫폼${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp 비디오 다운로드 도구" + echo -e "${gl_kjlan}67. ${color67}ddns-go 동적 DNS 관리 도구${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL 인증서 관리 플랫폼" + echo -e "${gl_kjlan}69. ${color69}SFTPGo 파일 전송 도구${gl_kjlan}70. ${color70}AstrBot 챗봇 프레임워크" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}71. ${color71}Navidrome 개인 음악 서버${gl_kjlan}72. ${color72}비트워든 비밀번호 관리자${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}73. ${color73}LibreTV 개인 영화${gl_kjlan}74. ${color74}MoonTV 개인 영화" + echo -e "${gl_kjlan}75. ${color75}멜로디 음악 마법사${gl_kjlan}76. ${color76}온라인 DOS 오래된 게임" + echo -e "${gl_kjlan}77. ${color77}Thunder 오프라인 다운로드 도구${gl_kjlan}78. ${color78}PandaWiki 지능형 문서 관리 시스템" + echo -e "${gl_kjlan}79. ${color79}베젤 서버 모니터링${gl_kjlan}80. ${color80}링크워든 북마크 관리" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet 화상 회의${gl_kjlan}82. ${color82}gpt-load 고성능 AI 투명 프록시" + echo -e "${gl_kjlan}83. ${color83}코마리 서버 모니터링 도구${gl_kjlan}84. ${color84}Wallos 개인 재무 관리 도구" + echo -e "${gl_kjlan}85. ${color85}이미치 픽처 비디오 매니저${gl_kjlan}86. ${color86}젤리핀 미디어 관리 시스템" + echo -e "${gl_kjlan}87. ${color87}SyncTV는 함께 영화를 볼 수 있는 훌륭한 도구입니다${gl_kjlan}88. ${color88}Owncast 자체 호스팅 라이브 스트리밍 플랫폼" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox 파일 익스프레스${gl_kjlan}90. ${color90}매트릭스 분산형 채팅 프로토콜" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea 비공개 코드 저장소${gl_kjlan}92. ${color92}FileBrowser 파일 관리자" + echo -e "${gl_kjlan}93. ${color93}Dufs 미니멀리스트 정적 파일 서버${gl_kjlan}94. ${color94}Gopeed 고속 다운로드 도구" + echo -e "${gl_kjlan}95. ${color95}종이 없는 문서 관리 플랫폼${gl_kjlan}96. ${color96}2FAuth 자체 호스팅 2단계 인증자" + echo -e "${gl_kjlan}97. ${color97}WireGuard 네트워킹(서버)${gl_kjlan}98. ${color98}WireGuard 네트워킹(클라이언트)" + echo -e "${gl_kjlan}99. ${color99}DSM Synology 가상 컴퓨터${gl_kjlan}100. ${color100}P2P 파일 동기화 도구 동기화" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI 영상 생성 도구${gl_kjlan}102. ${color102}VoceChat 다자간 온라인 채팅 시스템" + echo -e "${gl_kjlan}103. ${color103}Umami 웹사이트 통계 도구${gl_kjlan}104. ${color104}스트림 4계층 프록시 전달 도구" + echo -e "${gl_kjlan}105. ${color105}쓰위안 노트${gl_kjlan}106. ${color106}Drawix 오픈 소스 화이트보드 도구" + echo -e "${gl_kjlan}107. ${color107}PanSou 네트워크 디스크 검색${gl_kjlan}108. ${color108}LangBot 챗봇" + echo -e "${gl_kjlan}109. ${color109}ZFile 온라인 네트워크 디스크${gl_kjlan}110. ${color110}Karakeep 북마크 관리" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}다중 형식 파일 변환 도구${gl_kjlan}112. ${color112}행운의 대형 인트라넷 침투 도구" + echo -e "${gl_kjlan}113. ${color113}파이어폭스 브라우저" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}타사 애플리케이션 목록" + echo -e "${gl_kjlan}귀하의 앱이 여기에 표시되기를 원하십니까? 개발자 가이드를 확인하세요:${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # 앱 설명 가져오기 + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # 설치 상태 확인(appno.txt의 ID 일치) + # 여기서는 appno.txt에 기록되는 내용이 base_name(즉, 파일 이름)이라고 가정합니다. + if echo "$app_numbers" | grep -q "^$base_name$"; then + # 설치된 경우: show base_name - 설명 [설치됨](녹색) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text[설치됨]${gl_bai}" + else + # 설치되지 않은 경우: 정상적으로 표시됩니다. + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } - panel_app_manage() { - bt - } + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}모든 애플리케이션 데이터 백업${gl_kjlan}r. ${gl_bai}모든 앱 데이터 복원" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "선택사항을 입력하세요:" sub_choice + fi - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="탑 패널" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } - install_panel + panel_app_manage() { + bt + } + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } + install_panel - ;; - 2) - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } + ;; + 2|aapanel) - panel_app_manage() { - bt - } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - install_panel + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - ;; - 3) + panel_app_manage() { + bt + } - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + install_panel - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + ;; + 3|1p|1panel) - panel_app_uninstall() { - 1pctl uninstall - } + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - install_panel + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - ;; - 4) + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + panel_app_uninstall() { + 1pctl uninstall + } - docker_rum() { + install_panel - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + ;; + 4|npm) + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 - } + docker_rum() { - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - docker_app - ;; + } - 5) + local docker_describe="도메인 이름 액세스 추가를 지원하지 않는 Nginx 역방향 프록시 도구 패널." + local docker_url="공식 홈페이지 소개: https://nginxproxymanager.com/" + local docker_use="echo \"초기 사용자 이름: admin@example.com\"" + local docker_passwd="echo \"초기 비밀번호:changeme\"" + local app_size="1" - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + docker_app - docker_rum() { + ;; - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + 5|openlist) - } + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 + docker_rum() { - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - ;; + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 - 6) + } - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 - docker_rum() { + local docker_describe="gin 및 Solidjs로 구동되는 다중 저장소, 웹 브라우징 및 WebDAV를 지원하는 파일 목록 프로그램" + local docker_url="공식 홈페이지 소개: https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "로그인 사용자 이름 설정:" admin + read -e -p "로그인 사용자 비밀번호 설정:" admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - } + } - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + local docker_describe="webtop은 Ubuntu 기반 컨테이너입니다. 해당 IP에 접근할 수 없는 경우, 접근할 도메인 이름을 추가해주세요." + local docker_url="공식 홈페이지 소개: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - ;; - 7) + ;; + 7|nezha) + clear + send_stats "네자 빌드" + + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "Nezha를 구축하십시오" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "Nezha 모니터링$check_docker $update_status" - echo "오픈 소스, 가볍고 사용하기 쉬운 서버 모니터링 및 작동 및 유지 보수 도구" - echo "공식 웹 사이트 구성 문서 : https://nezha.wiki/guide/dashboard.html" - if docker inspect "$docker_name" &>/dev/null; then + echo -e "나타 모니터링$check_docker $update_status" + echo "오픈 소스, 가볍고 사용하기 쉬운 서버 모니터링 및 운영 및 유지 관리 도구" + echo "공식 웹사이트 구축 문서: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. 사용" + echo "------------------------" + echo "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택 항목을 입력하세요." choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1. 사용" - echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" - echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent 오프라인 BT 자기 다운로드 서비스" + local docker_url="공식 홈페이지 소개: https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "우체국을 짓다" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "우편 서비스$check_docker $update_status" + echo "poste.io는 오픈 소스 메일 서버 솔루션입니다." + echo "영상 소개: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "포트 감지" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}포트$port현재 사용 가능${gl_bai}" + else + echo -e "${gl_hong}포트$port현재는 이용할 수 없습니다${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "방문 주소:" + echo "https://$yuming" + fi - 9) - send_stats "우체국을 건설하십시오" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. 설치 2. 업데이트 3. 제거" + echo "------------------------" + echo "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택 항목을 입력하세요." choice - clear - echo -e "우체국 서비스$check_docker $update_status" - echo "Poste.io는 오픈 소스 메일 서버 솔루션입니다." - echo "비디오 소개 : https://www.bilibili.com/video/bv1wv421c71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "이메일 도메인 이름을 설정하십시오(예: mail.yuming.com):" yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "먼저 이 DNS 레코드를 구문 분석하세요." + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "계속하려면 아무 키나 누르세요..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "포트 감지" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}포트$port현재 사용 가능합니다${gl_bai}" - else - echo -e "${gl_hong}포트$port현재 사용할 수 없습니다${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io - if docker inspect "$docker_name" &>/dev/null; then - yuming=$(cat /home/docker/mail.txt) - echo "액세스 주소 :" + + add_app_id + + clear + echo "poste.io가 설치되었습니다" + echo "------------------------" + echo "다음 주소를 사용하여 poste.io에 액세스할 수 있습니다." echo "https://$yuming" - fi + echo "" - echo "------------------------" - echo "1. 설치 2. 업데이트 3. 제거" - echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" - echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "이메일 도메인 이름 (예 : Mail.yuming.com)을 설정하십시오." yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "이 DNS 레코드를 먼저 구문 분석하십시오" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "계속하려면 키를 누르십시오 ..." - read -n 1 -s -r -p "" + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i + yuming=$(cat /home/docker/mail.txt) + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.io가 설치되었습니다" + echo "------------------------" + echo "다음 주소를 사용하여 poste.io에 액세스할 수 있습니다." + echo "https://$yuming" + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "앱이 제거되었습니다." + ;; - install jq - install_docker + *) + break + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + esac + break_end + done - clear - echo "Poste.io가 설치되었습니다" - echo "------------------------" - echo "다음 주소를 사용하여 Poste.io에 액세스 할 수 있습니다." - echo "https://$yuming" - echo "" + ;; - ;; + 10|rocketchat) - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - clear - echo "Poste.io가 설치되었습니다" - echo "------------------------" - echo "다음 주소를 사용하여 Poste.io에 액세스 할 수 있습니다." - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - echo "앱이 제거되었습니다" - ;; + local app_id="10" + local app_name="Rocket.Chat 채팅 시스템" + local app_text="Rocket.Chat은 실시간 채팅, 음성 및 영상 통화, 파일 공유 및 기타 기능을 지원하는 오픈 소스 팀 커뮤니케이션 플랫폼입니다." + local app_url="공식소개 : https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - *) - break - ;; + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - esac - break_end - done + clear + ip_address + echo "설치 완료" + check_docker_app_ip + } - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "Rocket.chat이 설치되었습니다" + check_docker_app_ip + } - 10) + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "앱이 제거되었습니다." + } - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + docker_app_plus + ;; - clear - ip_address - echo "설치" - check_docker_app_ip - } - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "Rocket.chat이 설치되었습니다" - check_docker_app_ip - } - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "앱이 제거되었습니다" - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_plus - ;; + docker_rum() { - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - docker_rum() { + } + local docker_describe="ZenTao는 범용 프로젝트 관리 소프트웨어입니다" + local docker_url="공식 홈페이지 소개 : https://www.zentao.net/" + local docker_use="echo \"초기 사용자 이름: admin\"" + local docker_passwd="echo \"초기 비밀번호: 123456\"" + local app_size="2" + docker_app - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + ;; + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 - } + docker_rum() { - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app - ;; + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 - docker_rum() { + } + local docker_describe="Qinglong Panel은 예약된 작업 관리 플랫폼입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + ;; + 13|cloudreve) + + local app_id="13" + local app_name="클라우드리브 네트워크 디스크" + local app_text="cloudreve는 여러 클라우드 스토리지를 지원하는 네트워크 디스크 시스템입니다." + local app_url="영상 소개: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 13) + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "앱이 제거되었습니다." + } - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "설치" - check_docker_app_ip - } + docker_app_plus + ;; + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + } + local docker_describe="심플드로잉베드는 심플드로잉베드 프로그램입니다" + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "앱이 제거되었습니다" - } + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_plus - ;; + docker_rum() { - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 + } - docker_rum() { - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + local docker_describe="emby는 서버의 비디오 및 오디오를 구성하고 오디오 및 비디오를 클라이언트 장치로 스트리밍하는 데 사용할 수 있는 마스터-슬레이브 아키텍처 미디어 서버 소프트웨어입니다." + local docker_url="공식 홈페이지 소개 : https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - } + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server + } - docker_rum() { + local docker_describe="Speedtest 속도 측정 패널은 다양한 테스트 기능을 갖춘 VPS 네트워크 속도 테스트 도구이며 VPS 인바운드 및 아웃바운드 트래픽을 실시간으로 모니터링할 수도 있습니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server + ;; + 17|adguardhome) - } + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_rum() { - ;; - 17) + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 - docker_rum() { + } - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local docker_describe="AdGuardHome은 미래에 단순한 DNS 서버 이상의 역할을 할 네트워크 전체의 광고 차단 및 추적 방지 소프트웨어입니다." + local docker_url="공식 홈페이지 소개: https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + 18|onlyoffice) - ;; + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 + docker_rum() { - 18) + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 - docker_rum() { + } - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + local docker_describe="onlyoffice는 오픈 소스 온라인 오피스 도구로 매우 강력합니다!" + local docker_url="공식 홈페이지 소개 : https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; - } + 19|safeline) + send_stats "천둥 웅덩이를 만들어라" - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "썬더 풀 서비스$check_docker" + echo "레이치(Leichi)는 창팅테크놀로지(Changting Technology)가 개발한 WAF 사이트 방화벽 프로그램 패널로, 자동화된 방어를 위해 사이트를 반전시킬 수 있다." + echo "영상 소개: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" - ;; + echo "------------------------" + echo "1. 설치 2. 업데이트 3. 비밀번호 재설정 4. 제거" + echo "------------------------" + echo "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택 항목을 입력하세요." choice - 19) - send_stats "천둥 수영장을 건설하십시오" + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "썬더 풀 서비스$check_docker" - echo "Lei Chi는 변경 기술이 개발 한 WAF 사이트 방화벽 프로그램 패널로, 자동 방어를 위해 대행사 사이트를 역전시킬 수 있습니다." - echo "비디오 소개 : https://www.bilibili.com/video/bv1mz421t74c?t=0.1" - if docker inspect "$docker_name" &>/dev/null; then + add_app_id + clear + echo "Leichi WAF 패널이 설치되었습니다." check_docker_app_ip - fi - echo "" + docker exec safeline-mgt resetadmin - echo "------------------------" - echo "1. 설치 2. 업데이트 3. 비밀번호 재설정 4. 제거" - echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" - echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + ;; - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - clear - echo "Thunder Pool WAF 패널이 설치되었습니다" - check_docker_app_ip - docker exec safeline-mgt resetadmin + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "Leichi WAF 패널이 업데이트되었습니다." + check_docker_app_ip + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "기본 설치 디렉터리에 있다면 이제 프로젝트가 제거된 것입니다. 설치 디렉터리를 사용자 정의하는 경우 설치 디렉터리로 이동하여 직접 실행해야 합니다." + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer는 경량 도커 컨테이너 관리 패널입니다." + local docker_url="공식 홈페이지 소개 : https://www.portainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode는 강력한 온라인 코드 작성 도구입니다" + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="가동 시간 Kuma 사용하기 쉬운 자체 호스팅 모니터링 도구" + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos는 경량의 자체 호스팅 메모 센터입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "로그인 사용자 이름 설정:" admin + read -e -p "로그인 사용자 비밀번호 설정:" admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="웹탑은 중국어 버전의 Alpine 컨테이너를 기반으로 합니다. 해당 IP에 접근할 수 없는 경우, 접근할 도메인 이름을 추가해주세요." + local docker_url="공식 홈페이지 소개: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="400,000개 이상 배포된 Nextcloud는 다운로드할 수 있는 가장 인기 있는 로컬 콘텐츠 협업 플랫폼입니다." + local docker_url="공식 홈페이지 소개 : https://nextcloud.com/" + local docker_use="echo \"계정: nextcloud 비밀번호:$rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today는 HTTP 요청 예약 작업 자동 실행 프레임워크입니다." + local docker_url="공식 홈페이지 소개: https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="Dockge는 시각적 Docker 작성 컨테이너 관리 패널입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed는 즉시 사용할 수 있는 Javascript로 구현된 경량 속도 테스트 도구입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng는 비공개 및 비공개 검색 엔진 사이트입니다." + local docker_url="공식 홈페이지 소개 : https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="포토프리즘은 매우 강력한 개인 사진 앨범 시스템입니다." + local docker_url="공식 홈페이지 소개 : https://www.photoprism.app/" + local docker_use="echo \"계정: admin 비밀번호:$rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="이는 분할 병합, 변환, 재구성, 이미지 추가, 회전, 압축 등과 같은 PDF 파일에 대한 다양한 작업을 수행할 수 있는 docker를 사용하는 강력한 로컬 호스팅 웹 기반 PDF 조작 도구입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="이것은 강력한 차트 작성 소프트웨어입니다. 마인드맵, 토폴로지 다이어그램, 흐름도를 그릴 수 있습니다." + local docker_url="공식 홈페이지 소개 : https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel 서버, NAS 탐색 패널, 홈페이지, 브라우저 홈페이지" + local docker_url="공식 홈페이지 소개: https://doc.sun-panel.top/zh_cn/" + local docker_use="echo \"계정: admin@sun.cc 비밀번호: 12345678\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share는 자체 구축 가능한 파일 공유 플랫폼이자 WeTransfer의 대안입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="미니멀리스트 순간, 높은 모방 WeChat 순간, 멋진 삶을 기록하세요" + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo \"계정: admin 비밀번호: a123456\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat은 시장의 주류 AI 대형 모델인 ChatGPT/Claude/Gemini/Groq/Ollama를 통합합니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="자신의 IP 정보와 연결성을 확인하고 웹 패널을 통해 표시할 수 있는 다기능 IP 도구 상자입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "Xiaoya 가족 버킷" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go는 다양한 라이브 방송 플랫폼을 지원하는 라이브 방송 녹음 도구입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="간단한 온라인 SSH 연결 도구 및 SFTP 도구" + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="마우스 패널" + local panelurl="공식 주소:${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm은 강력한 온라인 SSH/VNC/RDP 연결 도구입니다." + local docker_url="공식 웹사이트 소개:${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="Rustdesk의 오픈 소스 원격 데스크톱(서버)은 자체 Sunflower 개인 서버와 유사합니다." + local docker_url="공식 홈페이지 소개: https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"원격 데스크톱 클라이언트에서 사용될 IP와 키를 기록하세요. 릴레이를 설치하려면 옵션 44로 이동하세요!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="Rustdesk의 오픈 소스 원격 데스크톱(릴레이)은 자체 Sunflower 개인 서버와 유사합니다." + local docker_url="공식 홈페이지 소개: https://rustdesk.com/zh-cn/" + local docker_use="echo \"원격 데스크톱 클라이언트를 다운로드하려면 공식 웹사이트로 이동하세요: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry는 Docker 이미지를 저장하고 배포하는 서비스입니다." + local docker_url="공식 홈페이지 소개: https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="Go를 사용하여 구현된 GHProxy는 일부 영역에서 Github 저장소 가져오기를 가속화하는 데 사용됩니다." + local docker_url="공식 홈페이지 소개: https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="프로메테우스 모니터링" + local app_text="Prometheus+Grafana 전사적 모니터링 시스템" + local app_url="공식 홈페이지 소개 : https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "설치 완료" + check_docker_app_ip + echo "초기 사용자 이름과 비밀번호는 admin입니다." + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "앱이 제거되었습니다." + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="이는 Prometheus 호스트 데이터 수집 구성 요소입니다. 모니터링되는 호스트에 배포하세요." + local docker_url="공식 홈페이지 소개: https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="이는 Prometheus 컨테이너 데이터 수집 구성 요소입니다. 모니터링되는 호스트에 배포하세요." + local docker_url="공식 홈페이지 소개: https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="이는 웹사이트 변경 감지, 보충 모니터링 및 알림을 위한 작은 도구입니다." + local docker_url="공식 홈페이지 소개: https://github.com/dgtlmoon/changeDetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE 오픈 병아리" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker 시각적 패널 시스템은 완전한 Docker 관리 기능을 제공합니다." + local docker_url="공식 홈페이지 소개: https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI는 새로운 llama3 대규모 언어 모델에 연결되는 대규모 언어 모델 웹 페이지 프레임워크입니다." + local docker_url="공식 홈페이지 소개: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMH 패널" + local panelurl="공식 주소 : https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI는 새로운 DeepSeek R1 대규모 언어 모델에 연결된 대규모 언어 모델 웹 페이지 프레임워크입니다." + local docker_url="공식 홈페이지 소개: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="DifyKnowledge Base" + local app_text="오픈 소스 LLM(대형 언어 모델) 애플리케이션 개발 플랫폼입니다. AI 생성을 위한 자체 호스팅 학습 데이터" + local app_url="공식 홈페이지: https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "설치 완료" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "앱이 제거되었습니다." + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="차세대 대형 모델 게이트웨이 및 AI 자산 관리 시스템" + local app_url="공식 홈페이지: https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "앱이 제거되었습니다." + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer 오픈 소스 요새 머신" + local app_text="오픈소스 권한 있는 액세스 관리(PAM) 도구입니다. 이 프로그램은 포트 80을 사용하며 액세스를 위한 도메인 이름 추가를 지원하지 않습니다." + local app_url="공식 소개: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "설치 완료" + check_docker_app_ip + echo "초기 사용자 이름: admin" + echo "초기 비밀번호: ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "앱이 업데이트되었습니다" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "앱이 제거되었습니다." + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="무료 오픈 소스 기계 번역 API, 완전 자체 호스팅 및 번역 엔진은 오픈 소스 Argos Translate 라이브러리에 의해 구동됩니다." + local docker_url="공식 홈페이지 소개: https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow 지식 기반" + local app_text="깊은 문서 이해를 기반으로 한 오픈소스 RAG(Retrieval Augmented Generation) 엔진" + local app_url="공식 홈페이지: https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "앱이 제거되었습니다." + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI는 대규모 언어 모델 웹 페이지 프레임워크로, 공식 단순화 버전은 모든 주요 모델에 대한 API 액세스를 지원합니다." + local docker_url="공식 홈페이지 소개: https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="개발자와 IT 작업자에게 매우 유용한 도구" + local docker_url="공식 홈페이지 소개: https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="강력한 자동화된 워크플로우 플랫폼입니다." + local docker_url="공식 홈페이지 소개: https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="동적 도메인 이름 확인을 위해 공용 IP(IPv4/IPv6)를 주요 DNS 서비스 제공업체에 실시간으로 자동 업데이트합니다." + local docker_url="공식 홈페이지 소개: https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="오픈 소스 무료 SSL 인증서 자동화 관리 플랫폼" + local docker_url="공식 홈페이지 소개: https://allinssl.com" + local docker_use="echo \"보안 입구: /allinssl\"" + local docker_passwd="echo \"사용자 이름: allinssl 비밀번호: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="언제 어디서나 무료 오픈 소스 SFTP FTP WebDAV 파일 전송 도구" + local docker_url="공식 홈페이지 소개 : https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="대규모 AI 모델에 대한 WeChat, QQ 및 TG 액세스를 지원하는 오픈 소스 AI 챗봇 프레임워크" + local docker_url="공식 홈페이지 소개: https://astrbot.app/" + local docker_use="echo \"사용자 이름: astrbot 비밀번호: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="경량, 고성능 음악 스트리밍 서버입니다." + local docker_url="공식 홈페이지 소개 : https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="귀하의 데이터를 통제할 수 있는 비밀번호 관리자" + local docker_url="공식 홈페이지 소개: https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "LibreTV 로그인 비밀번호 설정:" app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="무료 온라인 비디오 검색 및 시청 플랫폼" + local docker_url="공식 홈페이지 소개: https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="Moontv 개인 영화 및 TV" + local app_text="무료 온라인 비디오 검색 및 시청 플랫폼" + local app_url="영상소개 : https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "로그인 사용자 이름 설정:" admin + read -e -p "로그인 사용자 비밀번호 설정:" admin_password + read -e -p "인증 코드 입력:" shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "앱이 제거되었습니다." + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 - ;; + docker_rum() { - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - clear - echo "Thunder Pool WAF 패널이 업데이트되었습니다" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - echo "기본 설치 디렉토리 인 경우 프로젝트가 제거되었습니다. 설치 디렉토리를 사용자 정의하는 경우 직접 실행하려면 설치 디렉토리로 이동해야합니다." - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest - esac - break_end - done - ;; + } - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 + local docker_describe="음악을 더 잘 관리할 수 있도록 설계된 음악 마법사입니다." + local docker_url="공식 홈페이지 소개: https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer + ;; - } + 76|dosgame) - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 - ;; + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 + } + local docker_describe="중국의 DOS 게임 컬렉션 웹사이트입니다." + local docker_url="공식 홈페이지 소개: https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server + ;; - } + 77|xunlei) + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + docker_rum() { + read -e -p "로그인 사용자 이름 설정:" app_use + read -e -p "로그인 비밀번호 설정:" app_passwd - docker_rum() { + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + } - } + local docker_describe="오프라인 고속 BT 자기 다운로드 도구인 Xunlei" + local docker_url="공식 홈페이지 소개: https://github.com/cnk3x/xunlei" + local docker_use="echo \"휴대폰으로 Xunlei에 로그인하고 초대 코드를 입력하세요. 초대 코드: Xunlei Niutong\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 - docker_rum() { + 78|PandaWiki) - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki는 AI 대형 모델을 기반으로 하는 오픈 소스 지능형 문서 관리 시스템입니다. 포트 배포를 사용자 정의하지 않는 것이 좋습니다." + local app_url="공식 소개: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" - } + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + docker_app_install + } - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 - docker_rum() { + docker_app_uninstall() { + docker_app_install + } + docker_app_plus + ;; - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest - } + 79|beszel) + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; + docker_rum() { - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel - docker_rum() { + } - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + local docker_describe="Beszel은 가볍고 사용하기 쉬운 서버 모니터링입니다." + local docker_url="공식 홈페이지 소개: https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + 80|linkwarden) - docker_rum() { + local app_id="80" + local app_name="링크워든 북마크 관리" + local app_text="태그 지정, 검색 및 팀 협업을 지원하는 오픈 소스, 자체 호스팅 북마크 관리 플랫폼입니다." + local app_url="공식 홈페이지: https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden - } + # 공식 docker-compose 및 env 파일 다운로드 + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + # 임의의 키와 비밀번호 생성 + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - docker_rum() { + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + # 관리자 계정 정보 추가 + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - } + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + # 컨테이너 시작 + docker compose up -d - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 + clear + echo "설치 완료" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # 원래 변수 유지 + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "앱이 제거되었습니다." + } + + docker_app_plus - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest - } - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet 화상 회의" + local app_text="다자간 온라인 회의, 화면 공유, 암호화된 통신을 지원하는 오픈 소스 보안 화상 회의 솔루션입니다." + local app_url="공식 홈페이지: https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 + docker_app_install() { - docker_rum() { + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - } + } - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + } - docker_rum() { + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "앱이 제거되었습니다." + } - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + docker_app_plus - } + ;; - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 82|gpt-load) - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 + docker_rum() { - docker_rum() { + read -e -p "설정${docker_name}로그인 키(sk-다음과 같이 시작하는 문자와 숫자의 조합): sk-159kejilionyyds163:" app_passwd - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest - } + } + local docker_describe="고성능 AI 인터페이스 투명 프록시 서비스" + local docker_url="공식 홈페이지 소개: https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 - docker_rum() { - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + 83|komari) - } + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_rum() { - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - docker_rum() { + } - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + local docker_describe="경량 자체 호스팅 서버 모니터링 도구" + local docker_url="공식 홈페이지 소개: https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"기본 계정: admin 기본 비밀번호: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 - docker_rum() { + 84|wallos) - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 + docker_rum() { - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="공식 웹 사이트 소개 :${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest + } + local docker_describe="재무 관리를 위한 오픈 소스 개인 구독 추적기" + local docker_url="공식 홈페이지 소개: https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + ;; - docker_rum() { + 85|immich) - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } + local app_id="85" + local app_name="이미치 픽처 비디오 매니저" + local app_text="고성능 자체 호스팅 사진 및 비디오 관리 솔루션입니다." + local app_url="공식 홈페이지 소개: https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - docker_rum() { + docker compose up -d + + clear + echo "설치 완료" + check_docker_app_ip - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + } - } + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "앱이 제거되었습니다." + } + + docker_app_plus + + + ;; + + + 86|jellyfin) + + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 + + docker_rum() { + + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin + + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin + + + } + + local docker_describe="오픈 소스 미디어 서버 소프트웨어입니다" + local docker_url="공식 홈페이지 소개 : https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 87|synctv) + + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 + + docker_rum() { + + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv + + } + + local docker_describe="영화와 생방송을 원격으로 함께 시청할 수 있는 프로그램입니다. 동시 시청, 라이브 방송, 채팅 및 기타 기능을 제공합니다." + local docker_url="공식 홈페이지 소개: https://github.com/synctv-org/synctv" + local docker_use="echo \"초기 계정 및 비밀번호: root. 로그인 후 시간에 맞춰 로그인 비밀번호를 변경하세요\"" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 88|owncast) + + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 + + docker_rum() { + + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest + + + } + + local docker_describe="오픈 소스, 자체 구축한 무료 라이브 방송 플랫폼" + local docker_url="공식 홈페이지 소개 : https://owncast.online" + local docker_use="echo \"접속 주소 뒤에는 /admin이 붙어서 관리자 페이지에 접근합니다\"" + local docker_passwd="echo \"초기 계정 : admin 초기 비밀번호 : abc123 로그인 후 시간 내에 로그인 비밀번호를 변경해주세요\"" + local app_size="1" + docker_app + + ;; + + + + 89|file-code-box) + + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 + + docker_rum() { + + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest + + } + + local docker_describe="익명의 비밀번호로 텍스트와 파일을 공유하고, 빠른 배송과 같은 파일 픽업" + local docker_url="공식 홈페이지 소개: https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"접속 주소 뒤에는 /#/admin이 붙어서 관리자 페이지에 접속합니다\"" + local docker_passwd="echo \"관리자 비밀번호: FileCodeBox2023\"" + local app_size="1" + docker_app + + ;; - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 38) - send_stats "Xiaoya 가족 버킷" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; - 39) - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + 90|matrix) + + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 + + docker_rum() { + + add_yuming + + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate fi - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - docker_rum() { + echo "초기 사용자 또는 관리자를 생성합니다. 다음 사용자 이름과 비밀번호를 설정하고 관리자인지 여부를 설정하세요." + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - } + docker restart matrix - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + } - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Matrix는 분산형 채팅 프로토콜입니다." + local docker_url="공식 홈페이지 소개 : https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 41) + ;; - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } - panel_app_manage() { - panel-cli - } + 91|gitea) - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } + local app_id="91" - install_panel + local app_name="gitea 비공개 코드 저장소" + local app_text="GitHub에 가까운 경험을 제공하는 무료 차세대 코드 호스팅 플랫폼입니다." + local app_url="영상 소개: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - ;; + docker_app_install() { + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } - docker_rum() { - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - } - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "앱이 제거되었습니다." + } - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + docker_app_plus - docker_rum() { + ;; - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs - } - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + 92|filebrowser) - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - docker_rum() { + docker_rum() { - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - } + } - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="웹 기반 파일 관리자입니다" + local docker_url="공식 홈페이지 소개 : https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + ;; - docker_rum() { + 93|dufs) - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 - } + docker_rum() { - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 + } - docker_rum() { + local docker_describe="미니멀리스트 정적 파일 서버, 업로드 및 다운로드 지원" + local docker_url="공식 홈페이지 소개: https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest + ;; - } + 94|gopeed) - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 - 47) + docker_rum() { + read -e -p "로그인 사용자 이름 설정:" app_use + read -e -p "로그인 비밀번호 설정:" app_passwd + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + } - docker_app_install() { - prometheus_install - clear - ip_address - echo "설치" - check_docker_app_ip - echo "초기 사용자 이름과 비밀번호는 다음과 같습니다" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } + local docker_describe="여러 프로토콜을 지원하는 분산 고속 다운로드 도구" + local docker_url="공식 홈페이지 소개: https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest + ;; - rm -rf /home/docker/monitoring - echo "앱이 제거되었습니다" - } - docker_app_plus - ;; - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 + 95|paperless) - docker_rum() { + local app_id="95" - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + local app_name="종이 없는 문서 관리 플랫폼" + local app_text="오픈 소스 전자 문서 관리 시스템으로, 주요 목적은 종이 문서를 디지털화하고 관리하는 것입니다." + local app_url="영상 소개: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" + docker_app_install() { - } + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env + + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 - docker_rum() { + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } + - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "앱이 제거되었습니다." + } - } + docker_app_plus - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 - docker_rum() { + 96|2fauth) - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest + local app_id="96" - } + local app_name="2FAuth 자체 호스팅 2단계 인증자" + local app_text="자체 호스팅 2FA(2단계 인증) 계정 관리 및 확인 코드 생성 도구입니다." + local app_url="공식 홈페이지: https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_install() { + add_yuming + + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth + + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml + + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - 51) clear - send_stats "PVE 치킨" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + echo "설치 완료" + check_docker_app_ip + } - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - docker_rum() { - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "앱이 제거되었습니다." + } - } + docker_app_plus - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 - docker_rum() { - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + 97|wgs) - } + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_rum() { - 54) + read -e -p "네트워크의 클라이언트 수를 입력하십시오(기본값 5):" COUNT + COUNT=${COUNT:-5} + read -e -p "WireGuard 네트워크 세그먼트(기본값 10.13.13.0)를 입력하세요." NETWORK + NETWORK=${NETWORK:-10.13.13.0} - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } + ip link delete wg0 &>/dev/null - panel_app_manage() { - panel_app_install - } + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - panel_app_uninstall() { - panel_app_install - } - install_panel - ;; + sleep 3 + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - 55) - frps_panel - ;; + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " - 56) - frpc_panel - ;; + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' - docker_rum() { + docker restart wireguard - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + sleep 2 + echo + echo -e "${gl_huang}모든 클라이언트 QR 코드 구성:${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}모든 클라이언트 구성 코드:${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}각 클라이언트에 대한 모든 출력을 구성합니다. 사용방법은 다음과 같습니다.${gl_bai}" + echo -e "${gl_lv}1. 휴대폰에 wg APP을 다운로드하고 위의 QR 코드를 스캔하면 빠르게 인터넷에 연결됩니다.${gl_bai}" + echo -e "${gl_lv}2. Windows용 클라이언트를 다운로드하고 구성 코드를 복사하여 네트워크에 연결합니다.${gl_bai}" + echo -e "${gl_lv}3. 스크립트를 사용하여 Linux에 WG 클라이언트를 배포하고 구성 코드를 복사하여 네트워크에 연결합니다.${gl_bai}" + echo -e "${gl_lv}공식 클라이언트 다운로드 방법: https://www.wireguard.com/install/${gl_bai}" + break_end - } + } - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local docker_describe="최신 고성능 가상 사설망 도구" + local docker_url="공식 홈페이지 소개 : https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + 98|wgc) - docker compose up -d - clear - echo "설치" - check_docker_app_ip - } + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } + docker_rum() { - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "앱이 제거되었습니다" - } + mkdir -p /home/docker/wireguard/config/ - docker_app_plus + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - ;; + # 디렉터리가 없으면 생성 + mkdir -p "$(dirname "$CONFIG_FILE")" - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + echo "클라이언트 구성을 붙여넣고 Enter를 두 번 눌러 저장하세요." - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + # 변수 초기화 + input="" + empty_line_count=0 - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + # 사용자 입력을 한 줄씩 읽습니다. + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done + # 구성 파일 쓰기 + echo "$input" > "$CONFIG_FILE" - docker compose up -d - clear - echo "설치" - check_docker_app_ip - } + echo "클라이언트 구성이 다음에 저장되었습니다.$CONFIG_FILE" - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + ip link delete wg0 &>/dev/null - docker compose up -d - clear - echo "설치" - check_docker_app_ip + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - } + sleep 3 - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "앱이 제거되었습니다" - } + docker logs wireguardc - docker_app_plus + break_end - ;; + } + local docker_describe="최신 고성능 가상 사설망 도구" + local docker_url="공식 홈페이지 소개 : https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 60) + ;; - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "설치" - check_docker_app_ip - echo "초기 사용자 이름 : 관리자" - echo "초기 비밀번호 : changeme" - } + 99|dsm) + local app_id="99" - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "앱이 업데이트되었습니다" - } + local app_name="dsm 시놀로지 가상 머신" + local app_text="Docker 컨테이너의 가상 DSM" + local app_url="공식 웹사이트: https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" + docker_app_install() { - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "앱이 제거되었습니다" - } + read -e -p "CPU 코어 수를 설정합니다(기본값 2):" CPU_CORES + local CPU_CORES=${CPU_CORES:-2} - docker_app_plus - ;; + read -e -p "메모리 크기 설정(기본 4G):" RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - docker_rum() { + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d - } + clear + echo "설치 완료" + check_docker_app_ip + } - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "앱이 제거되었습니다." + } - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "설치" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } + docker_app_plus - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "앱이 제거되었습니다" - } + ;; - docker_app_plus - ;; + 100|syncthing) - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 - docker_rum() { + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main + local docker_describe="Dropbox 및 Resilio Sync와 유사하지만 완전히 분산된 오픈 소스 P2P 파일 동기화 도구입니다." + local docker_url="공식 홈페이지 소개: https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI 영상 생성 도구" + local app_text="MoneyPrinterTurbo는 AI 대형 모델을 사용하여 고화질 짧은 동영상을 합성하는 도구입니다." + local app_url="공식 웹사이트: https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "앱이 제거되었습니다." + } - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + docker_app_plus - docker_rum() { + ;; - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" - } + 102|vocechat) - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - 66) - yt_menu_pro - ;; + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + } - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local docker_describe="독립적인 배포를 지원하는 개인용 클라우드 소셜 미디어 채팅 서비스입니다." + local docker_url="공식 홈페이지 소개: https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + 103|umami) + local app_id="103" + local app_name="Umami 웹사이트 통계 도구" + local app_text="Google Analytics와 유사한 오픈 소스, 가볍고 개인정보 보호 친화적인 웹사이트 분석 도구입니다." + local app_url="공식 웹사이트: https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + echo "초기 사용자 이름: admin" + echo "초기 비밀번호 : umami" + } + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "앱이 제거되었습니다." + } - docker_rum() { + docker_app_plus - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo + ;; - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + 104|nginx-stream) + stream_panel + ;; - } - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 105|siyuan) + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 + docker_rum() { - docker_rum() { + read -e -p "로그인 비밀번호 설정:" app_passwd - mkdir -p /home/docker/astrbot/data + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + } - } + local docker_describe="Siyuan Notes는 개인 정보 보호를 최우선으로 하는 지식 관리 시스템입니다." + local docker_url="공식 홈페이지 소개: https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + 106|drawnix) - docker_rum() { + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_rum() { - } + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="마인드맵, 플로우차트 등을 통합한 강력한 오픈소스 화이트보드 도구입니다." + local docker_url="공식 홈페이지 소개: https://github.com/plait-board/ drawix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { + 107|pansou) - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou는 고성능 네트워크 디스크 리소스 검색 API 서비스입니다." + local docker_url="공식 홈페이지 소개: https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 73) - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 - docker_rum() { + 108|langbot) + local app_id="108" + local app_name="LangBot 챗봇" + local app_text="오픈 소스 대형 언어 모델 기반 인스턴트 메시징 로봇 개발 플랫폼입니다." + local app_url="공식 홈페이지: https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - read -e -p "libretv 로그인 비밀번호 설정 :" app_passwd + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "앱이 제거되었습니다." + } - ;; + docker_app_plus + ;; - 74) - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + 109|zfile) - docker_rum() { + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - read -e -p "MOONTV 로그인 비밀번호 설정 :" app_passwd + docker_rum() { - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest - } + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="개인이나 소규모 팀에 적합한 온라인 네트워크 디스크 프로그램입니다." + local docker_url="공식 홈페이지 소개: https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 75) + ;; - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 - docker_rum() { + 110|karakeep) + local app_id="110" + local app_name="karakeep 북마크 관리" + local app_text="데이터 수집가를 위해 설계된 인공 지능 기능을 갖춘 자체 호스팅 북마크 앱입니다." + local app_url="공식 홈페이지: https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + docker compose up -d + clear + echo "설치 완료" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "앱이 제거되었습니다." + } + docker_app_plus - ;; + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 + 111|convertx) - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - } + docker_rum() { - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} + } - ;; + local docker_describe="강력한 다중 형식 파일 변환 도구입니다(문서, 이미지, 오디오 및 비디오 등 지원). 도메인 이름 액세스를 추가하는 것이 좋습니다." + local docker_url="프로젝트 주소: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - 77) + ;; - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 - docker_rum() { + 112|lucky) - read -e -p "설정${docker_name}로그인 사용자 이름 :" app_use - read -e -p "설정${docker_name}로그인 비밀번호 :" app_passwd + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # Lucky는 호스트 네트워크 모드를 사용하므로 여기서 포트는 기록/설명 참조용으로만 사용되며 실제로는 애플리케이션 자체에 의해 제어됩니다(기본값 16601). + local docker_port=8112 - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + docker_rum() { - } + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + echo "Lucky가 초기화되기를 기다리는 중..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - ;; + } + local docker_describe="Lucky는 DDNS, 역방향 프록시, WOL 및 기타 기능을 지원하는 대규모 인트라넷 침투 및 포트 전달 관리 도구입니다." + local docker_url="프로젝트 주소: https://github.com/gdy666/lucky" + local docker_use="echo \"기본 계정 비밀번호: 666\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 78) - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + 113|firefox) - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 - docker_app_update() { - docker_app_install - } + docker_rum() { + read -e -p "로그인 비밀번호 설정:" admin_password - docker_app_uninstall() { - docker_app_install - } + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - docker_app_plus - ;; + local docker_describe="웹 페이지를 통해 데스크톱 브라우저 인터페이스에 대한 직접 액세스를 지원하는 Docker에서 실행되는 Firefox 브라우저입니다." + local docker_url="프로젝트 주소: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 79) + b) + clear + send_stats "모든 애플리케이션 백업" - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}백업 중$backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_rum() { + while true; do + clear + echo "생성된 백업 파일: /$backup_filename" + read -e -p "백업 데이터를 원격 서버로 전송하시겠습니까? (예/아니요):" choice + case "$choice" in + [Yy]) + read -e -p "원격 서버 IP를 입력하세요:" remote_ip + read -e -p "대상 서버 SSH 포트 [기본값 22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel + if [ -z "$remote_ip" ]; then + echo "오류: 원격 서버 IP를 입력하세요." + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "원격 서버/루트 디렉터리로 파일이 전송되었습니다." + else + echo "전송할 파일을 찾을 수 없습니다." + fi + break + ;; + *) + echo "참고: 현재 백업에는 docker 프로젝트만 포함되며, Pagoda, 1panel 등 웹사이트 구축 패널의 데이터 백업은 포함되지 않습니다." + break + ;; + esac + done - } + ;; - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + r) + root_use + send_stats "모든 앱 복원" + echo "사용 가능한 애플리케이션 백업" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "최신 백업을 복원하려면 Enter 키를 누르고, 지정된 백업을 복원하려면 백업 파일 이름을 입력하고, 종료하려면 0을 입력하세요." filename - ;; + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # 사용자가 파일명을 입력하지 않으면 최신 압축 패키지가 사용됩니다. + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}압축 해제 중$filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "애플리케이션 데이터가 복원되었습니다. 현재 해당 애플리케이션을 복원하려면 지정된 애플리케이션 메뉴에 수동으로 진입한 후 애플리케이션을 업데이트하시기 바랍니다." + else + echo "압축된 패키지를 찾을 수 없습니다." + fi + ;; - 0) - kejilion - ;; - *) - echo "잘못된 입력!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}오류: 번호가 없습니다.${sub_choice}애플리케이션 구성${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do clear - send_stats "백엔드 작업 공간" - echo -e "백엔드 작업 공간" - echo -e "이 시스템은 백엔드에서 실행할 수있는 작업 공간을 제공하며 장기 작업을 수행하는 데 사용할 수 있습니다." - echo -e "SSH를 분리하더라도 작업 공간의 작업이 중단되지 않으며 백그라운드의 작업이 거주됩니다." - echo -e "${gl_huang}힌트:${gl_bai}작업 공간에 입력 한 후 Ctrl+B를 사용하고 D 만 눌러 작업 공간을 종료하십시오!" + send_stats "백엔드 작업공간" + echo -e "백엔드 작업공간" + echo -e "시스템은 장기간 작업을 수행하는 데 사용할 수 있는 백그라운드에서 영구적으로 실행될 수 있는 작업 공간을 제공합니다." + echo -e "SSH 연결을 끊더라도 작업 공간의 작업은 중단되지 않으며 작업은 백그라운드에 유지됩니다." + echo -e "${gl_huang}힌트:${gl_bai}워크스페이스 진입 후 Ctrl+b를 누른 후 d만 눌러 워크스페이스를 종료하세요!" echo -e "${gl_kjlan}------------------------" - echo "현재 기존 작업 공간 목록" + echo "현재 존재하는 작업공간 목록" echo -e "${gl_kjlan}------------------------" tmux list-sessions echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}작업 공간 번호 1" - echo -e "${gl_kjlan}2. ${gl_bai}작업 공간 2 번" - echo -e "${gl_kjlan}3. ${gl_bai}작업 공간 번호 3" - echo -e "${gl_kjlan}4. ${gl_bai}작업 공간 No. 4" - echo -e "${gl_kjlan}5. ${gl_bai}작업 공간 번호 5" - echo -e "${gl_kjlan}6. ${gl_bai}작업 공간 No. 6" - echo -e "${gl_kjlan}7. ${gl_bai}작업 공간 번호 7" - echo -e "${gl_kjlan}8. ${gl_bai}작업 공간 번호 8" - echo -e "${gl_kjlan}9. ${gl_bai}작업 공간 No. 9" - echo -e "${gl_kjlan}10. ${gl_bai}작업 공간 번호 10" + echo -e "${gl_kjlan}1. ${gl_bai}작업 영역 1" + echo -e "${gl_kjlan}2. ${gl_bai}작업 영역 2" + echo -e "${gl_kjlan}3. ${gl_bai}작업 영역 3" + echo -e "${gl_kjlan}4. ${gl_bai}작업 영역 4" + echo -e "${gl_kjlan}5. ${gl_bai}작업 공간 5번" + echo -e "${gl_kjlan}6. ${gl_bai}작업 영역 6" + echo -e "${gl_kjlan}7. ${gl_bai}작업 영역 7" + echo -e "${gl_kjlan}8. ${gl_bai}작업 영역 8" + echo -e "${gl_kjlan}9. ${gl_bai}작업 공간 9호" + echo -e "${gl_kjlan}10. ${gl_bai}작업공간 10" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}SSH 거주 모드${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}22. ${gl_bai}작업 공간을 작성/입력하십시오" - echo -e "${gl_kjlan}23. ${gl_bai}배경 작업 공간에 명령을 주입합니다" - echo -e "${gl_kjlan}24. ${gl_bai}지정된 작업 공간을 삭제하십시오" + echo -e "${gl_kjlan}21. ${gl_bai}SSH 상주 모드${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}22. ${gl_bai}작업공간 생성/입력" + echo -e "${gl_kjlan}23. ${gl_bai}백그라운드 작업 공간에 명령 삽입" + echo -e "${gl_kjlan}24. ${gl_bai}지정된 작업공간 삭제" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in @@ -10676,7 +13165,7 @@ linux_work() { clear install tmux local SESSION_NAME="work1" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; @@ -10684,63 +13173,63 @@ linux_work() { clear install tmux local SESSION_NAME="work2" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 3) clear install tmux local SESSION_NAME="work3" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 4) clear install tmux local SESSION_NAME="work4" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 5) clear install tmux local SESSION_NAME="work5" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 6) clear install tmux local SESSION_NAME="work6" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 7) clear install tmux local SESSION_NAME="work7" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 8) clear install tmux local SESSION_NAME="work8" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 9) clear install tmux local SESSION_NAME="work9" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; 10) clear install tmux local SESSION_NAME="work10" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" + send_stats "작업공간 시작$SESSION_NAME" tmux_run ;; @@ -10748,30 +13237,30 @@ linux_work() { while true; do clear if grep -q 'tmux attach-session -t sshd || tmux new-session -s sshd' ~/.bashrc; then - local tmux_sshd_status="${gl_lv}开启${gl_bai}" + local tmux_sshd_status="${gl_lv}켜다${gl_bai}" else - local tmux_sshd_status="${gl_hui}关闭${gl_bai}" + local tmux_sshd_status="${gl_hui}폐쇄${gl_bai}" fi - send_stats "SSH 거주 모드" - echo -e "SSH 거주 모드${tmux_sshd_status}" - echo "SSH 연결이 활성화 된 후에는 거주 모드에 직접 입력하여 이전 작업 상태로 돌아갑니다." + send_stats "SSH 상주 모드" + echo -e "SSH 상주 모드${tmux_sshd_status}" + echo "SSH 연결을 연 후 바로 상주 모드로 들어가고 이전 작업 상태로 바로 돌아갑니다." echo "------------------------" - echo "1. 2를 켜십시오. 2를 끕니다" + echo "1. 켜짐 2. 꺼짐" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" gongzuoqu_del + read -e -p "선택사항을 입력하세요:" gongzuoqu_del case "$gongzuoqu_del" in 1) install tmux local SESSION_NAME="sshd" - send_stats "작업 공간을 시작하십시오$SESSION_NAME" - grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\ n# 자동으로 tmux 세션을 입력 \ nif [[-z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc + send_stats "작업공간 시작$SESSION_NAME" + grep -q "tmux attach-session -t sshd" ~/.bashrc || echo -e "\n# 자동으로 tmux 세션 시작\nif [[ -z \"\$TMUX\" ]]; then\n tmux attach-session -t sshd || tmux new-session -s sshd\nfi" >> ~/.bashrc source ~/.bashrc tmux_run ;; 2) - sed -i '/# 自动进入 tmux 会话/,+4d' ~/.bashrc + sed -i '/# 자동으로 tmux 세션을 입력합니다/,+4d' ~/.bashrc tmux kill-window -t sshd ;; *) @@ -10782,29 +13271,29 @@ linux_work() { ;; 22) - read -e -p "1001 KJ001 Work1과 같이 생성하거나 입력 한 작업 공간의 이름을 입력하십시오." SESSION_NAME + read -e -p "1001 kj001 work1과 같이 생성하거나 입력한 작업공간의 이름을 입력하세요." SESSION_NAME tmux_run - send_stats "사용자 정의 작업 공간" + send_stats "맞춤형 작업공간" ;; 23) - read -e -p "Curl -fssl https://get.docker.com | 쉿:" tmuxd + read -e -p "다음과 같이 백그라운드에서 실행하려는 명령을 입력하십시오. 컬 -fsSL https://get.docker.com | 쉿:" tmuxd tmux_run_d - send_stats "배경 작업 공간에 명령을 주입합니다" + send_stats "백그라운드 작업 공간에 명령 삽입" ;; 24) - read -e -p "삭제하려는 작업 공간의 이름을 입력하십시오." gongzuoqu_name + read -e -p "삭제하려는 작업공간의 이름을 입력하세요:" gongzuoqu_name tmux kill-window -t $gongzuoqu_name - send_stats "작업 공간을 삭제합니다" + send_stats "작업공간 삭제" ;; 0) kejilion ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -10823,59 +13312,155 @@ linux_work() { +# 지능형 스위칭 미러 소스 기능 +switch_mirror() { + # 선택적 매개변수, 기본값은 false입니다. + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # 사용자 국가 가져오기 + local country + country=$(curl -s ipinfo.io/country) + + echo "감지된 국가:$country" + + if [ "$country" = "CN" ]; then + echo "국내 미러 소스를 사용하세요..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "공식 미러 소스를 사용하세요..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "SSH 방어" + while true; do + + check_f2b_status + echo -e "SSH 방어 프로그램$check_f2b_status" + echo "fall2ban은 무차별 대입 크래킹을 방지하는 SSH 도구입니다." + echo "공식 웹사이트 소개:${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. 방어 프로그램 설치" + echo "------------------------" + echo "2. SSH 차단 기록 보기" + echo "3. 실시간 로그 모니터링" + echo "------------------------" + echo "9. 방어 프로그램 제거" + echo "------------------------" + echo "0. 이전 메뉴로 돌아가기" + echo "------------------------" + read -e -p "선택사항을 입력하세요:" sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban 방어 프로그램이 제거되었습니다." + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { while true; do clear - # Send_stats "시스템 도구" + # send_stats "시스템 도구" echo -e "시스템 도구" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}스크립트 스타트 업 단축키 키를 설정하십시오${gl_kjlan}2. ${gl_bai}로그인 암호를 수정하십시오" - echo -e "${gl_kjlan}3. ${gl_bai}루트 암호 로그인 모드${gl_kjlan}4. ${gl_bai}지정된 버전의 Python을 설치하십시오" - echo -e "${gl_kjlan}5. ${gl_bai}모든 포트를 엽니 다${gl_kjlan}6. ${gl_bai}SSH 연결 포트를 수정하십시오" - echo -e "${gl_kjlan}7. ${gl_bai}DNS 주소를 최적화합니다${gl_kjlan}8. ${gl_bai}원 클릭 복직 시스템${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}9. ${gl_bai}루트 계정을 비활성화하여 새 계정을 생성하십시오${gl_kjlan}10. ${gl_bai}우선 순위 IPv4/IPv6을 전환하십시오" + echo -e "${gl_kjlan}1. ${gl_bai}스크립트 시작 단축키 설정${gl_kjlan}2. ${gl_bai}로그인 비밀번호 변경" + echo -e "${gl_kjlan}3. ${gl_bai}ROOT 비밀번호 로그인 모드${gl_kjlan}4. ${gl_bai}지정된 버전의 Python 설치" + echo -e "${gl_kjlan}5. ${gl_bai}모든 포트 열기${gl_kjlan}6. ${gl_bai}SSH 연결 포트 수정" + echo -e "${gl_kjlan}7. ${gl_bai}DNS 주소 최적화${gl_kjlan}8. ${gl_bai}한 번의 클릭으로 시스템을 다시 설치${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}9. ${gl_bai}ROOT 계정을 비활성화하고 새 계정을 만듭니다.${gl_kjlan}10. ${gl_bai}우선 순위 ipv4/ipv6 전환" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}항구 직업 상태를 확인하십시오${gl_kjlan}12. ${gl_bai}가상 메모리 크기를 수정합니다" + echo -e "${gl_kjlan}11. ${gl_bai}항만점유현황 확인${gl_kjlan}12. ${gl_bai}가상 메모리 크기 수정" echo -e "${gl_kjlan}13. ${gl_bai}사용자 관리${gl_kjlan}14. ${gl_bai}사용자/비밀번호 생성기" - echo -e "${gl_kjlan}15. ${gl_bai}시스템 시간대 조정${gl_kjlan}16. ${gl_bai}BBR3 가속도를 설정하십시오" - echo -e "${gl_kjlan}17. ${gl_bai}방화벽 고급 관리자${gl_kjlan}18. ${gl_bai}호스트 이름을 수정하십시오" - echo -e "${gl_kjlan}19. ${gl_bai}스위치 시스템 업데이트 소스${gl_kjlan}20. ${gl_bai}타이밍 작업 관리" + echo -e "${gl_kjlan}15. ${gl_bai}시스템 시간대 조정${gl_kjlan}16. ${gl_bai}BBR3 가속 설정" + echo -e "${gl_kjlan}17. ${gl_bai}방화벽 고급 관리자${gl_kjlan}18. ${gl_bai}호스트 이름 수정" + echo -e "${gl_kjlan}19. ${gl_bai}시스템 업데이트 소스 전환${gl_kjlan}20. ${gl_bai}예약된 작업 관리" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}기본 호스트 구문 분석${gl_kjlan}22. ${gl_bai}SSH 방어 프로그램" - echo -e "${gl_kjlan}23. ${gl_bai}현재 한도의 자동 종료${gl_kjlan}24. ${gl_bai}루트 비공개 키 로그인 모드" - echo -e "${gl_kjlan}25. ${gl_bai}TG-BOT 시스템 모니터링 및 조기 경고${gl_kjlan}26. ${gl_bai}OpenSsh 고위험 취약점 수정 (Xiuyuan)" - echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linux 커널 업그레이드${gl_kjlan}28. ${gl_bai}Linux 시스템에서 커널 매개 변수의 최적화${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}29. ${gl_bai}바이러스 스캐닝 도구${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}파일 관리자" + echo -e "${gl_kjlan}21. ${gl_bai}기본 호스트 확인${gl_kjlan}22. ${gl_bai}SSH 방어 프로그램" + echo -e "${gl_kjlan}23. ${gl_bai}전류 제한 자동 종료${gl_kjlan}24. ${gl_bai}ROOT 개인 키 로그인 모드" + echo -e "${gl_kjlan}25. ${gl_bai}TG-bot 시스템 모니터링 및 조기 경보${gl_kjlan}26. ${gl_bai}OpenSSH 고위험 취약점 수정" + echo -e "${gl_kjlan}27. ${gl_bai}Red Hat Linux 커널 업그레이드${gl_kjlan}28. ${gl_bai}Linux 시스템 커널 매개변수 최적화${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}29. ${gl_bai}바이러스 검사 도구${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}파일 관리자" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}스위치 시스템 언어${gl_kjlan}32. ${gl_bai}명령 라인 미화 도구${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}시스템 재활용 빈을 설정하십시오${gl_kjlan}34. ${gl_bai}시스템 백업 및 복구" + echo -e "${gl_kjlan}31. ${gl_bai}시스템 언어 전환${gl_kjlan}32. ${gl_bai}명령줄 미화 도구${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}시스템 휴지통 설정${gl_kjlan}34. ${gl_bai}시스템 백업 및 복구" echo -e "${gl_kjlan}35. ${gl_bai}SSH 원격 연결 도구${gl_kjlan}36. ${gl_bai}하드 디스크 파티션 관리 도구" - echo -e "${gl_kjlan}37. ${gl_bai}명령 줄 기록${gl_kjlan}38. ${gl_bai}RSYNC 원격 동기화 도구" + echo -e "${gl_kjlan}37. ${gl_bai}명령줄 기록${gl_kjlan}38. ${gl_bai}rsync 원격 동기화 도구" + echo -e "${gl_kjlan}39. ${gl_bai}명령 즐겨찾기${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}게시판${gl_kjlan}66. ${gl_bai}원 스톱 시스템 최적화${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}99. ${gl_bai}서버를 다시 시작하십시오${gl_kjlan}100. ${gl_bai}개인 정보 및 보안" - echo -e "${gl_kjlan}101. ${gl_bai}K 명령의 고급 사용${gl_huang}★${gl_bai} ${gl_kjlan}102. ${gl_bai}기술 라이온 스크립트를 제거하십시오" + echo -e "${gl_kjlan}41. ${gl_bai}메시지 보드${gl_kjlan}66. ${gl_bai}원스톱 시스템 튜닝${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}99. ${gl_bai}서버를 다시 시작하세요${gl_kjlan}100. ${gl_bai}개인 정보 보호 및 보안" + echo -e "${gl_kjlan}101. ${gl_bai}k 명령의 고급 사용법${gl_huang}★${gl_bai} ${gl_kjlan}102. ${gl_bai}기술 사자 스크립트 제거" echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아갑니다" + echo -e "${gl_kjlan}0. ${gl_bai}메인 메뉴로 돌아가기" echo -e "${gl_kjlan}------------------------${gl_bai}" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) while true; do clear - read -e -p "바로 가기 키를 입력하십시오 (종료하려면 0을 입력하십시오) :" kuaijiejian + read -e -p "바로가기 키를 입력하십시오(종료하려면 0을 입력하십시오):" kuaijiejian if [ "$kuaijiejian" == "0" ]; then break_end linux_Settings fi find /usr/local/bin/ -type l -exec bash -c 'test "$(readlink -f {})" = "/usr/local/bin/k" && rm -f {}' \; ln -s /usr/local/bin/k /usr/local/bin/$kuaijiejian - echo "바로 가기 키가 설정되어 있습니다" - send_stats "스크립트 바로 가기 키가 설정되었습니다" + echo "단축키가 설정되었습니다" + send_stats "스크립트 단축키가 설정되었습니다" break_end linux_Settings done @@ -10883,8 +13468,8 @@ linux_Settings() { 2) clear - send_stats "로그인 비밀번호를 설정하십시오" - echo "로그인 비밀번호를 설정하십시오" + send_stats "로그인 비밀번호를 설정하세요" + echo "로그인 비밀번호를 설정하세요" passwd ;; 3) @@ -10895,18 +13480,18 @@ linux_Settings() { 4) root_use - send_stats "PY 버전 관리" + send_stats "py 버전 관리" echo "파이썬 버전 관리" - echo "비디오 소개 : https://www.bilibili.com/video/bv1pm42157ck?t=0.1" + echo "영상 소개: https://www.bilibili.com/video/BV1Pm42157cK?t=0.1" echo "---------------------------------------" - echo "이 기능은 Python에서 공식적으로 지원되는 모든 버전을 완벽하게 설치합니다!" + echo "이 기능은 Python이 공식적으로 지원하는 모든 버전을 원활하게 설치할 수 있습니다!" local VERSION=$(python3 -V 2>&1 | awk '{print $2}') - echo -e "현재 파이썬 버전 번호 :${gl_huang}$VERSION${gl_bai}" + echo -e "현재 Python 버전 번호:${gl_huang}$VERSION${gl_bai}" echo "------------" - echo "권장 버전 : 3.12 3.11 3.10 3.9 3.8 2.7" - echo "더 많은 버전 : https://www.python.org/downloads/" + echo "권장 버전: 3.12 3.11 3.10 3.9 3.8 2.7" + echo "더 많은 버전 확인: https://www.python.org/downloads/" echo "------------" - read -e -p "설치하려는 Python 버전 번호를 입력하십시오 (종료하려면 0을 입력하십시오) :" py_new_v + read -e -p "설치하려는 Python 버전 번호를 입력하세요(종료하려면 0 입력)." py_new_v if [[ "$py_new_v" == "0" ]]; then @@ -10943,7 +13528,7 @@ linux_Settings() { apk update && apk add git apk add --no-cache bash gcc musl-dev libffi-dev openssl-dev bzip2-dev zlib-dev readline-dev sqlite-dev libc6-compat linux-headers make xz-dev build-base ncurses-dev else - echo "알 수없는 패키지 관리자!" + echo "알 수 없는 패키지 관리자입니다!" return fi @@ -10972,55 +13557,55 @@ EOF rm -rf $(pyenv root)/cache/* local VERSION=$(python -V 2>&1 | awk '{print $2}') - echo -e "현재 파이썬 버전 번호 :${gl_huang}$VERSION${gl_bai}" - send_stats "스크립트 Py 버전을 스위치하십시오" + echo -e "현재 Python 버전 번호:${gl_huang}$VERSION${gl_bai}" + send_stats "스크립트 PY 버전 전환" ;; 5) root_use - send_stats "포트 열기" + send_stats "열린 포트" iptables_open remove iptables-persistent ufw firewalld iptables-services > /dev/null 2>&1 - echo "모든 포트가 열려 있습니다" + echo "모든 포트가 열려 있습니다." ;; 6) root_use - send_stats "SSH 포트를 수정하십시오" + send_stats "SSH 포트 수정" while true; do clear sed -i 's/#Port/Port/' /etc/ssh/sshd_config - # 현재 SSH 포트 번호를 읽으십시오 + # 현재 SSH 포트 번호 읽기 local current_port=$(grep -E '^ *Port [0-9]+' /etc/ssh/sshd_config | awk '{print $2}') - # 현재 SSH 포트 번호를 인쇄하십시오 + # 현재 SSH 포트 번호 인쇄 echo -e "현재 SSH 포트 번호는 다음과 같습니다.${gl_huang}$current_port ${gl_bai}" echo "------------------------" - echo "1 ~ 65535 범위의 포트 번호가있는 숫자 (종료하려면 0을 입력하십시오)" + echo "포트 번호 범위는 1~65535입니다. (종료하려면 0을 입력하세요.)" - # 사용자에게 새 SSH 포트 번호를 입력하라는 메시지 - read -e -p "새로운 SSH 포트 번호를 입력하십시오 :" new_port + # 사용자에게 새 SSH 포트 번호를 묻는 메시지 표시 + read -e -p "새 SSH 포트 번호를 입력하세요." new_port # 포트 번호가 유효한 범위 내에 있는지 확인 if [[ $new_port =~ ^[0-9]+$ ]]; then # 检查输入是否为数字 if [[ $new_port -ge 1 && $new_port -le 65535 ]]; then - send_stats "SSH 포트가 수정되었습니다" + send_stats "SSH 포트가 수정되었습니다." new_ssh_port elif [[ $new_port -eq 0 ]]; then - send_stats "SSH 포트 수정을 종료하십시오" + send_stats "SSH 포트 수정 종료" break else - echo "포트 번호는 유효하지 않으며 1에서 65535 사이의 숫자를 입력하십시오." - send_stats "잘못된 SSH 포트 입력" + echo "포트 번호가 잘못되었습니다. 1~65535 사이의 숫자를 입력하세요." + send_stats "잘못된 SSH 포트가 입력되었습니다." break_end fi else - echo "입력이 유효하지 않으므로 번호를 입력하십시오." - send_stats "잘못된 SSH 포트 입력" + echo "입력이 잘못되었습니다. 숫자를 입력하세요." + send_stats "잘못된 SSH 포트가 입력되었습니다." break_end fi done @@ -11039,8 +13624,8 @@ EOF ;; 9) root_use - send_stats "신규 사용자는 루트를 비활성화합니다" - read -e -p "새 사용자 이름을 입력하십시오 (종료하려면 0을 입력하십시오) :" new_username + send_stats "신규 사용자에 대한 루트 비활성화" + read -e -p "새 사용자 이름을 입력하십시오(종료하려면 0을 입력하십시오):" new_username if [ "$new_username" == "0" ]; then break_end linux_Settings @@ -11049,6 +13634,8 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root @@ -11059,43 +13646,42 @@ EOF 10) root_use - send_stats "V4/V6 우선 순위를 설정하십시오" + send_stats "v4/v6 우선순위 설정" while true; do clear - echo "V4/V6 우선 순위를 설정하십시오" + echo "v4/v6 우선순위 설정" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then - echo -e "현재 네트워크 우선 순위 설정 :${gl_huang}IPv4${gl_bai}우선 사항" + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then + echo -e "현재 네트워크 우선순위 설정:${gl_huang}IPv4${gl_bai}우선 사항" else - echo -e "현재 네트워크 우선 순위 설정 :${gl_huang}IPv6${gl_bai}우선 사항" + echo -e "현재 네트워크 우선순위 설정:${gl_huang}IPv6${gl_bai}우선 사항" fi + echo "" echo "------------------------" - echo "1. IPv4 우선 순위 2. IPv6 우선 순위 3. IPv6 수리 도구" + echo "1. IPv4 우선 2. IPv6 우선 3. IPv6 복구 도구" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선호하는 네트워크를 선택하십시오." choice + read -e -p "선호하는 네트워크를 선택하세요:" choice case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "IPv4 우선 순위로 전환되었습니다" - send_stats "IPv4 우선 순위로 전환되었습니다" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 - echo "IPv6 우선 순위로 전환되었습니다" - send_stats "IPv6 우선 순위로 전환되었습니다" + rm -f /etc/gai.conf + echo "먼저 IPv6로 전환됨" + send_stats "먼저 IPv6로 전환됨" ;; 3) clear bash <(curl -L -s jhb.ovh/jb/v6.sh) - echo "이 기능은 마스터 JHB가 제공합니다." - send_stats "IPv6 수정" + echo "이 기능은 jhb에서 제공합니다. 감사합니다!" + send_stats "IPv6 수리" ;; *) @@ -11113,21 +13699,21 @@ EOF 12) root_use - send_stats "가상 메모리를 설정합니다" + send_stats "가상 메모리 설정" while true; do clear - echo "가상 메모리를 설정합니다" + echo "가상 메모리 설정" local swap_used=$(free -m | awk 'NR==3{print $3}') local swap_total=$(free -m | awk 'NR==3{print $2}') local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - echo -e "현재 가상 메모리 :${gl_huang}$swap_info${gl_bai}" + echo -e "현재 가상 메모리:${gl_huang}$swap_info${gl_bai}" echo "------------------------" - echo "1. 1024m 2. 할당 2048m 3. 4096m 할당 4. 사용자 정의 크기" + echo "1. 1024M 할당 2. 2048M 할당 3. 4096M 할당 4. 사용자 정의 크기" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택사항을 입력하세요:" choice case "$choice" in 1) @@ -11141,15 +13727,15 @@ EOF ;; 3) - send_stats "4G 가상 메모리가 설정되었습니다" + send_stats "4G 가상 메모리가 설정되었습니다." add_swap 4096 ;; 4) - read -e -p "가상 메모리 크기 (단위 M)를 입력하십시오." new_swap + read -e -p "가상 메모리 크기(단위 M)를 입력하세요." new_swap add_swap "$new_swap" - send_stats "사용자 정의 가상 메모리가 설정되었습니다" + send_stats "사용자 정의 가상 메모리 세트" ;; *) @@ -11165,7 +13751,7 @@ EOF send_stats "사용자 관리" echo "사용자 목록" echo "----------------------------------------------------------------------------" - printf "%-24s %-34s %-20s %-10s\n" "用户名" "用户权限" "用户组" "sudo权限" + printf "%-24s %-34s %-20s %-10s\n" "사용자 이름" "사용자 권한" "사용자 그룹" "sudo 권한" while IFS=: read -r username _ userid groupid _ _ homedir shell; do local groups=$(groups "$username" | cut -d : -f 2) local sudo_status=$(sudo -n -lU "$username" 2>/dev/null | grep -q '(ALL : ALL)' && echo "Yes" || echo "No") @@ -11176,22 +13762,22 @@ EOF echo "" echo "계정 운영" echo "------------------------" - echo "1. 일반 계정 만들기 2. 프리미엄 계정 만들기" + echo "1. 일반 계정 생성 2. 프리미엄 계정 생성" echo "------------------------" - echo "3. 최고 권한을 부여 4. 최고 권한을 취소하십시오." + echo "3. 가장 높은 권한을 부여합니다. 4. 가장 높은 권한을 제거합니다." echo "------------------------" - echo "5. 계정을 삭제하십시오" + echo "5. 계정 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - # 사용자에게 새 사용자 이름을 입력하도록 프롬프트하십시오 - read -e -p "새 사용자 이름을 입력하십시오 :" new_username + # 사용자에게 새 사용자 이름을 묻는 메시지 표시 + read -e -p "새 사용자 이름을 입력하세요:" new_username - # 새 사용자를 생성하고 비밀번호를 설정하십시오 + # 새로운 사용자 생성 및 비밀번호 설정 useradd -m -s /bin/bash "$new_username" passwd "$new_username" @@ -11199,33 +13785,37 @@ EOF ;; 2) - # 사용자에게 새 사용자 이름을 입력하도록 프롬프트하십시오 - read -e -p "새 사용자 이름을 입력하십시오 :" new_username + # 사용자에게 새 사용자 이름을 묻는 메시지 표시 + read -e -p "새 사용자 이름을 입력하세요:" new_username - # 새 사용자를 생성하고 비밀번호를 설정하십시오 + # 새로운 사용자 생성 및 비밀번호 설정 useradd -m -s /bin/bash "$new_username" passwd "$new_username" - # 새로운 사용자에게 허가를 부여하십시오 + # 새 사용자에게 sudo 권한 부여 echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + install sudo + echo "작업이 완료되었습니다." ;; 3) - read -e -p "사용자 이름을 입력하십시오 :" username - # 새로운 사용자에게 허가를 부여하십시오 + read -e -p "사용자 이름을 입력하세요:" username + # 새 사용자에게 sudo 권한 부여 echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) - read -e -p "사용자 이름을 입력하십시오 :" username - # Sudoers 파일에서 사용자의 Sudo 권한을 제거하십시오 + read -e -p "사용자 이름을 입력하세요:" username + # sudoers 파일에서 사용자의 sudo 권한을 제거합니다. sed -i "/^$username\sALL=(ALL:ALL)\sALL/d" /etc/sudoers ;; 5) - read -e -p "삭제하려면 사용자 이름을 입력하십시오." username - # 사용자와 홈 디렉토리를 삭제하십시오 + read -e -p "삭제하려는 사용자 이름을 입력하세요:" username + # 사용자 및 해당 홈 디렉터리 삭제 userdel -r "$username" ;; @@ -11247,12 +13837,12 @@ EOF done echo "" - echo "임의 이름" + echo "임의의 이름" echo "------------------------" local first_names=("John" "Jane" "Michael" "Emily" "David" "Sophia" "William" "Olivia" "James" "Emma" "Ava" "Liam" "Mia" "Noah" "Isabella") local last_names=("Smith" "Johnson" "Brown" "Davis" "Wilson" "Miller" "Jones" "Garcia" "Martinez" "Williams" "Lee" "Gonzalez" "Rodriguez" "Hernandez") - # 5 개의 임의의 사용자 이름을 생성합니다 + # 5개의 무작위 사용자 이름 생성 for i in {1..5}; do local first_name_index=$((RANDOM % ${#first_names[@]})) local last_name_index=$((RANDOM % ${#last_names[@]})) @@ -11261,27 +13851,27 @@ EOF done echo "" - echo "무작위 uuid" + echo "무작위 UUID" echo "------------------------" for i in {1..5}; do uuid=$(cat /proc/sys/kernel/random/uuid) - echo "무작위 uuid$i: $uuid" + echo "무작위 UUID$i: $uuid" done echo "" - echo "16 비트 랜덤 비밀번호" + echo "16자리 랜덤 비밀번호" echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) - echo "랜덤 비밀번호$i: $password" + echo "임의의 비밀번호$i: $password" done echo "" - echo "32 비트 랜덤 비밀번호" + echo "32비트 임의 비밀번호" echo "------------------------" for i in {1..5}; do local password=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c32) - echo "랜덤 비밀번호$i: $password" + echo "임의의 비밀번호$i: $password" done echo "" @@ -11289,46 +13879,46 @@ EOF 15) root_use - send_stats "시간대를 변경하십시오" + send_stats "시간대 변경" while true; do clear echo "시스템 시간 정보" - # 현재 시스템 시간대를 얻으십시오 + # 현재 시스템 시간대 가져오기 local timezone=$(current_timezone) - # 현재 시스템 시간을 얻으십시오 + # 현재 시스템 시간을 가져옵니다 local current_time=$(date +"%Y-%m-%d %H:%M:%S") - # 시간대와 시간을 보여줍니다 - echo "현재 시스템 시간대 :$timezone" - echo "현재 시스템 시간 :$current_time" + # 시간대 및 시간 표시 + echo "현재 시스템 시간대:$timezone" + echo "현재 시스템 시간:$current_time" echo "" - echo "시간대 스위칭" + echo "시간대 스위치" echo "------------------------" echo "아시아" - echo "1. 중국의 상하이 시간 2. 중국의 홍콩 시간" - echo "3. 일본의 도쿄 시간 4. 한국의 서울 시간" - echo "5. 싱가포르 시간 6. 인도의 콜카타 시간" - echo "7. UAE 8의 두바이 시간. 호주 시드니 시간" - echo "9. 태국 방콕에서의 시간" + echo "1. 중국 상하이 시간 2. 중국 홍콩 시간" + echo "3. 일본 도쿄 시간 4. 한국 서울 시간" + echo "5. 싱가포르 시간 6. 콜카타, 인도 시간" + echo "7. 아랍에미리트 두바이 시간 8. 호주 시드니 시간" + echo "9. 태국 방콕 시간" echo "------------------------" echo "유럽" - echo "11. 영국의 런던 시간 12. 프랑스의 파리 시간" - echo "13. 베를린 시간, 독일 14. 모스크바 시간, 러시아" - echo "15. 네덜란드에서 우트레흐트 시간 16. 스페인의 마드리드 시간" + echo "11. 영국 런던 시간 12. 프랑스 파리 시간" + echo "13. 독일 베를린 시간 14. 러시아 모스크바 시간" + echo "15. 네덜란드 위트라흐트 시간 16. 스페인 마드리드 시간" echo "------------------------" echo "미국" - echo "21. 서양 시간 22. 동부 시간" + echo "21. 미국 서부 시간 22. 미국 동부 시간" echo "23. 캐나다 시간 24. 멕시코 시간" echo "25. 브라질 시간 26. 아르헨티나 시간" echo "------------------------" - echo "31. UTC 글로벌 표준 시간" + echo "31. UTC 세계 표준시" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in @@ -11371,21 +13961,21 @@ EOF 18) root_use - send_stats "호스트 이름을 수정하십시오" + send_stats "호스트 이름 수정" while true; do clear local current_hostname=$(uname -n) - echo -e "현재 호스트 이름 :${gl_huang}$current_hostname${gl_bai}" + echo -e "현재 호스트 이름:${gl_huang}$current_hostname${gl_bai}" echo "------------------------" - read -e -p "새 호스트 이름을 입력하십시오 (종료하려면 0을 입력하십시오) :" new_hostname + read -e -p "새 호스트 이름을 입력하십시오(종료하려면 0을 입력하십시오):" new_hostname if [ -n "$new_hostname" ] && [ "$new_hostname" != "0" ]; then if [ -f /etc/alpine-release ]; then # Alpine echo "$new_hostname" > /etc/hostname hostname "$new_hostname" else - # Debian, Ubuntu, Centos 등과 같은 다른 시스템 + # Debian, Ubuntu, CentOS 등과 같은 다른 시스템 hostnamectl set-hostname "$new_hostname" sed -i "s/$current_hostname/$new_hostname/g" /etc/hostname systemctl restart systemd-hostnamed @@ -11403,11 +13993,11 @@ EOF echo "::1 $new_hostname localhost localhost.localdomain ipv6-localhost ipv6-loopback" >> /etc/hosts fi - echo "호스트 이름은 다음으로 변경되었습니다.$new_hostname" - send_stats "호스트 이름이 변경되었습니다" + echo "호스트 이름이 다음으로 변경되었습니다.$new_hostname" + send_stats "호스트 이름이 변경됨" sleep 1 else - echo "종료, 호스트 이름이 변경되지 않았습니다." + echo "호스트 이름을 변경하지 않고 종료되었습니다." break fi done @@ -11415,30 +14005,35 @@ EOF 19) root_use - send_stats "시스템 업데이트 소스를 변경하십시오" + send_stats "시스템 업데이트 소스 변경" clear - echo "업데이트 소스 영역을 선택하십시오" - echo "LinuxMirrors에 연결하여 시스템 업데이트 소스를 전환하십시오" + echo "업데이트 소스 지역 선택" + echo "LinuxMirrors에 액세스하여 시스템 업데이트 소스 전환" echo "------------------------" - echo "1. 중국 본토 [기본값] 2. 중국 본토 [교육 네트워크] 3. 해외 지역" + echo "1. 중국 본토 [기본값] 2. 중국 본토 [교육 네트워크] 3. 해외 지역 4. 업데이트 소스의 지능형 전환" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" choice + read -e -p "선택 항목을 입력하세요." choice case $choice in 1) - send_stats "중국 본토의 기본 소스" + send_stats "중국 본토 기본 소스" bash <(curl -sSL https://linuxmirrors.cn/main.sh) ;; 2) - send_stats "중국 본토의 교육 원" + send_stats "중국 본토 교육 소스" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --edu ;; 3) - send_stats "해외 출신" + send_stats "해외 소스" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "업데이트 소스의 지능적인 전환" + switch_mirror false false + ;; + *) echo "취소" ;; @@ -11448,62 +14043,62 @@ EOF ;; 20) - send_stats "타이밍 작업 관리" + send_stats "예약된 작업 관리" while true; do clear check_crontab_installed clear - echo "시간이 정한 작업 목록" + echo "예약된 작업 목록" crontab -l echo "" echo "작동하다" echo "------------------------" - echo "1. 타이밍 작업 추가 2. 타이밍 작업 삭제 3. 타이밍 작업 편집" + echo "1. 예약된 작업 추가 2. 예약된 작업 삭제 3. 예약된 작업 편집" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) - read -e -p "새 작업에 대한 실행 명령을 입력하십시오." newquest + read -e -p "새 작업의 실행 명령을 입력하십시오:" newquest echo "------------------------" echo "1. 월간 작업 2. 주간 작업" - echo "3. 일일 작업 4. 시간당 작업" + echo "3. 일일 작업 4. 시간별 작업" echo "------------------------" - read -e -p "선택을 입력하십시오 :" dingshi + read -e -p "선택사항을 입력하세요:" dingshi case $dingshi in 1) - read -e -p "작업을 수행하려면 매월 어느 날을 선택합니까? (1-30) :" day + read -e -p "작업을 실행하기로 선택한 달의 날짜는 무엇입니까? (1-30):" day (crontab -l ; echo "0 0 $day * * $newquest") | crontab - > /dev/null 2>&1 ;; 2) - read -e -p "작업을 수행 할 일주일을 선택합니까? (0-6, 0은 일요일을 나타냅니다) :" weekday + read -e -p "작업을 수행할 요일을 선택하시겠습니까? (0-6, 0은 일요일을 나타냄):" weekday (crontab -l ; echo "0 0 * * $weekday $newquest") | crontab - > /dev/null 2>&1 ;; 3) - read -e -p "매일 작업을 수행 할 시간을 선택하십시오. (시간, 0-23) :" hour + read -e -p "매일 몇 시에 작업을 수행하기로 선택하시나요? (시간, 0-23):" hour (crontab -l ; echo "0 $hour * * * $newquest") | crontab - > /dev/null 2>&1 ;; 4) - read -e -p "작업을 수행하기 위해 몇 분의 시간을 입력합니까? (Mins, 0-60) :" minute + read -e -p "작업을 실행해야 하는 시간을 입력하세요. (분, 0-60):" minute (crontab -l ; echo "$minute * * * * $newquest") | crontab - > /dev/null 2>&1 ;; *) break # 跳出 ;; esac - send_stats "시간이 정한 작업을 추가하십시오" + send_stats "예약된 작업 추가" ;; 2) - read -e -p "삭제 해야하는 키워드를 입력하십시오." kquest + read -e -p "삭제할 작업의 키워드를 입력하세요:" kquest crontab -l | grep -v "$kquest" | crontab - - send_stats "타이밍 작업을 삭제하십시오" + send_stats "예약된 작업 삭제" ;; 3) crontab -e - send_stats "타이밍 작업 편집" + send_stats "예약된 작업 편집" ;; *) break # 跳出循环,退出菜单 @@ -11515,32 +14110,32 @@ EOF 21) root_use - send_stats "지역 호스트 구문 분석" + send_stats "로컬 호스트 확인" while true; do clear - echo "기본 호스트 구문 분석 목록" - echo "여기에 구문 분석 일치를 추가하면 더 이상 동적 구문 분석이 사용되지 않습니다." + echo "기본 호스트 확인 목록" + echo "여기에 파싱 매칭을 추가하면 더 이상 동적 파싱이 사용되지 않습니다." cat /etc/hosts echo "" echo "작동하다" echo "------------------------" - echo "1. 새 구문 분석 추가 2. 구문 분석 주소 삭제" + echo "1. 새로운 해상도 추가 2. 해상도 주소 삭제" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" host_dns + read -e -p "선택사항을 입력하세요:" host_dns case $host_dns in 1) - read -e -p "새 구문 분석 기록 형식을 입력하십시오 : 110.25.5.33 Kejilion.pro :" addhost + read -e -p "새로운 구문 분석 기록 형식을 입력하세요: 110.25.5.33 kejilion.pro:" addhost echo "$addhost" >> /etc/hosts - send_stats "로컬 호스트 구문 분석이 추가되었습니다" + send_stats "로컬 호스트 해상도가 추가되었습니다." ;; 2) - read -e -p "삭제 해야하는 구문 분석 컨텐츠의 키워드를 입력하십시오." delhost + read -e -p "삭제해야 하는 구문 분석된 콘텐츠의 키워드를 입력하세요." delhost sed -i "/$delhost/d" /etc/hosts - send_stats "로컬 호스트 구문 분석 및 삭제" + send_stats "로컬 호스트 확인 및 삭제" ;; *) break # 跳出循环,退出菜单 @@ -11550,109 +14145,53 @@ EOF ;; 22) - root_use - send_stats "SSH 방어" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH 방어 프로그램$check_docker" - echo "FAIL2BAN은 무자비한 힘을 방지하는 SSH 도구입니다" - echo "공식 웹 사이트 소개 :${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1. 방어 프로그램을 설치하십시오" - echo "------------------------" - echo "2. SSH 차단 레코드보기" - echo "3. 실시간 로그 모니터링" - echo "------------------------" - echo "9. 방어 프로그램을 제거하십시오" - echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" - echo "------------------------" - read -e -p "선택을 입력하십시오 :" sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2ban 방어 프로그램은 제거되었습니다" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; 23) root_use - send_stats "현재 제한 종료 기능" + send_stats "전류 제한 차단 기능" while true; do clear - echo "현재 제한 종료 기능" - echo "비디오 소개 : https://www.bilibili.com/video/bv1mc411j7qd?t=0.1" + echo "전류 제한 차단 기능" + echo "영상 소개: https://www.bilibili.com/video/BV1mC411j7Qd?t=0.1" echo "------------------------------------------------" - echo "서버 트래픽 계산을 다시 시작하는 현재 트래픽 사용이 지워집니다!" + echo "서버가 다시 시작되면 현재 트래픽 사용량이 지워집니다!" output_status - echo -e "${gl_kjlan}총 수신 :${gl_bai}$rx" - echo -e "${gl_kjlan}총 보내기 :${gl_bai}$tx" + echo -e "${gl_kjlan}받은 총액:${gl_bai}$rx" + echo -e "${gl_kjlan}보낸 총액:${gl_bai}$tx" - # limiting_shut_down.sh 파일이 있는지 확인하십시오 + # Limiting_Shut_down.sh 파일이 있는지 확인하세요. if [ -f ~/Limiting_Shut_down.sh ]; then - # threshold_gb의 값을 얻으십시오 + # Threshold_gb 값을 가져옵니다. local rx_threshold_gb=$(grep -oP 'rx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) local tx_threshold_gb=$(grep -oP 'tx_threshold_gb=\K\d+' ~/Limiting_Shut_down.sh) - echo -e "${gl_lv}현재 세트 입력-스테이션 전류 한계 임계 값은 다음과 같습니다.${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" - echo -e "${gl_lv}현재 아웃 바운드 전류 한계 임계 값은 다음과 같습니다.${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" + echo -e "${gl_lv}현재 설정된 인바운드 트래픽 제한 임계값은 다음과 같습니다.${gl_huang}${rx_threshold_gb}${gl_lv}G${gl_bai}" + echo -e "${gl_lv}현재 설정된 아웃바운드 트래픽 제한 임계값은 다음과 같습니다.${gl_huang}${tx_threshold_gb}${gl_lv}GB${gl_bai}" else - echo -e "${gl_hui}전류 제한 종료 기능이 활성화되지 않았습니다${gl_bai}" + echo -e "${gl_hui}현재 제한 종료 기능이 현재 활성화되어 있지 않습니다.${gl_bai}" fi echo echo "------------------------------------------------" - echo "시스템은 실제 트래픽이 1 분마다 임계 값에 도달하는지 여부를 감지하고 서버가 도착하면 자동으로 종료됩니다!" + echo "시스템은 매분마다 실제 트래픽이 임계값에 도달했는지 여부를 감지하고 임계값에 도달한 후 자동으로 서버를 종료합니다!" echo "------------------------" - echo "1. 현재 한계 셧다운 함수 켜기 2. 현재 한계 종료 함수 비활성화" + echo "1. 전류 제한 종료 기능을 활성화합니다. 2. 전류 제한 종료 기능을 비활성화합니다." echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" Limiting + read -e -p "선택사항을 입력하세요:" Limiting case "$Limiting" in 1) - # 새 가상 메모리 크기를 입력하십시오 - echo "실제 서버에 트래픽이 100g 인 경우 트래픽 오류 나 오버플로를 피하기 위해 임계 값을 95G로 설정하고 전원을 미리 차단할 수 있습니다." - read -e -p "들어오는 트래픽 임계 값을 입력하십시오 (단위 G, 기본값은 100G) :" rx_threshold_gb + # 새 가상 메모리 크기 입력 + echo "실제 서버의 트래픽이 100G만 있는 경우 임계값을 95G로 설정하고 미리 종료하여 트래픽 오류나 오버플로를 방지할 수 있습니다." + read -e -p "인바운드 트래픽 임계값을 입력하십시오(단위는 G, 기본값은 100G)." rx_threshold_gb rx_threshold_gb=${rx_threshold_gb:-100} - read -e -p "아웃 바운드 트래픽 임계 값을 입력하십시오 (단위 G, 기본값은 100g) :" tx_threshold_gb + read -e -p "아웃바운드 트래픽 임계값을 입력하십시오(단위는 G, 기본값은 100G)." tx_threshold_gb tx_threshold_gb=${tx_threshold_gb:-100} - read -e -p "트래픽 재설정 날짜를 입력하십시오 (매월 1 일에 기본 재설정) :" cz_day + read -e -p "트래픽 재설정 날짜를 입력하세요(기본적으로 매월 1일 재설정)." cz_day cz_day=${cz_day:-1} cd ~ @@ -11665,15 +14204,15 @@ EOF (crontab -l ; echo "* * * * * ~/Limiting_Shut_down.sh") | crontab - > /dev/null 2>&1 crontab -l | grep -v 'reboot' | crontab - (crontab -l ; echo "0 1 $cz_day * * reboot") | crontab - > /dev/null 2>&1 - echo "전류 제한 종료가 설정되었습니다" - send_stats "전류 제한 종료가 설정되었습니다" + echo "전류 제한 종료가 설정되었습니다." + send_stats "전류 제한 종료가 설정되었습니다." ;; 2) check_crontab_installed crontab -l | grep -v '~/Limiting_Shut_down.sh' | crontab - crontab -l | grep -v 'reboot' | crontab - rm ~/Limiting_Shut_down.sh - echo "전류 제한 종료 기능이 꺼졌습니다" + echo "전류 제한 차단 기능이 꺼졌습니다." ;; *) break @@ -11686,37 +14225,37 @@ EOF 24) root_use - send_stats "개인 키 로그인" + send_stats "개인키 로그인" while true; do clear - echo "루트 비공개 키 로그인 모드" - echo "비디오 소개 : https://www.bilibili.com/video/bv1q4421x78n?t=209.4" + echo "ROOT 개인 키 로그인 모드" + echo "영상 소개: https://www.bilibili.com/video/BV1Q4421X78n?t=209.4" echo "------------------------------------------------" - echo "키 쌍이 생성되며 SSH 로그인을위한보다 안전한 방법" + echo "SSH를 통해 더욱 안전하게 로그인할 수 있는 키 쌍이 생성됩니다." echo "------------------------" - echo "1. 새 키 생성 2. 기존 키 가져 오기 3. 기본 키보기" + echo "1. 새 키 생성 2. 기존 키 가져오기 3. 로컬 키 보기" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" host_dns + read -e -p "선택사항을 입력하세요:" host_dns case $host_dns in 1) - send_stats "새로운 키를 생성하십시오" + send_stats "새 키 생성" add_sshkey break_end ;; 2) - send_stats "기존 공개 키를 가져옵니다" + send_stats "기존 공개 키 가져오기" import_sshkey break_end ;; 3) - send_stats "로컬 비밀 키를보십시오" + send_stats "로컬 키 보기" echo "------------------------" - echo "공개 키 정보" + echo "공개키 정보" cat ~/.ssh/authorized_keys echo "------------------------" echo "개인 키 정보" @@ -11735,18 +14274,18 @@ EOF 25) root_use - send_stats "전보 경고" - echo "TG-BOT 모니터링 및 조기 경고 기능" - echo "비디오 소개 : https://youtu.be/vll-eb3z_ty" + send_stats "전신 경고" + echo "TG-bot 모니터링 및 조기경보 기능" + echo "영상소개: https://youtu.be/vLL-eb3Z_TY" echo "------------------------------------------------" - echo "기본 CPU, 메모리, 하드 디스크, 트래픽 및 SSH 로그인의 실시간 모니터링 및 조기 경고를 실현하려면 조기 경고를 받으려면 TG Robot API 및 사용자 ID를 구성해야합니다." - echo "임계 값에 도달하면 사용자가 사용자에게 전송됩니다." - echo -e "${gl_hui}- 트래픽과 관련하여 서버를 다시 시작하면 다시 계산됩니다.${gl_bai}" - read -e -p "계속할거야? (Y/N) :" choice + echo "로컬 CPU, 메모리, 하드 디스크, 트래픽 및 SSH 로그인에 대한 실시간 모니터링 및 경고를 달성하려면 경고를 수신하도록 tg 로봇 API 및 사용자 ID를 구성해야 합니다." + echo "임계값에 도달하면 경고 메시지가 사용자에게 전송됩니다." + echo -e "${gl_hui}- 트래픽에 관해서는 서버를 다시 시작하면 다시 계산됩니다 -${gl_bai}" + read -e -p "계속하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) - send_stats "전보 경고가 활성화되었습니다" + send_stats "텔레그램 경고 활성화됨" cd ~ install nano tmux bc jq check_crontab_installed @@ -11768,7 +14307,7 @@ EOF sed -i "4i$(grep '^CHAT_ID=' ~/TG-check-notify.sh)" TG-SSH-check-notify.sh chmod +x ~/TG-SSH-check-notify.sh - # ~/.profile 파일에 추가하십시오 + # ~/.profile 파일에 추가 if ! grep -q 'bash ~/TG-SSH-check-notify.sh' ~/.profile > /dev/null 2>&1; then echo 'bash ~/TG-SSH-check-notify.sh' >> ~/.profile if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -11779,21 +14318,21 @@ EOF source ~/.profile clear - echo "TG-BOT 조기 경고 시스템이 시작되었습니다" - echo -e "${gl_hui}다른 시스템의 루트 디렉토리에 TG-Check-Notify.sh 경고 파일을 배치하고 직접 사용할 수도 있습니다!${gl_bai}" + echo "TG-bot 조기경보 시스템이 활성화되었습니다." + echo -e "${gl_hui}TG-check-notify.sh 경고 파일을 다른 컴퓨터의 루트 디렉터리에 넣고 직접 사용할 수도 있습니다!${gl_bai}" ;; [Nn]) echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; 26) root_use - send_stats "SSH에서 고위험 취약점을 수정하십시오" + send_stats "고위험 SSH 취약점 수정" cd ~ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/upgrade_openssh9.8p1.sh chmod +x ~/upgrade_openssh9.8p1.sh @@ -11837,7 +14376,7 @@ EOF ;; 37) clear - send_stats "명령 줄 기록" + send_stats "명령줄 기록" get_history_file() { for file in "$HOME"/.bash_history "$HOME"/.ash_history "$HOME"/.zsh_history "$HOME"/.local/share/fish/fish_history; do [ -f "$file" ] && { echo "$file"; return; } @@ -11853,98 +14392,102 @@ EOF ;; + 39) + clear + linux_fav + ;; + 41) clear - send_stats "게시판" - echo "Technology Lion 게시판은 공식 커뮤니티로 옮겨졌습니다! 공식 커뮤니티에 메시지를 남겨주세요!" - echo "https://bbs.kejilion.pro/" + send_stats "메시지 보드" + echo "Technology Lion 공식 게시판을 방문해 보세요. 스크립트에 대한 아이디어가 있으시면 교환 메시지를 남겨주세요!" + echo "https://board.kejilion.pro" + echo "공개 비밀번호: kejilion.sh" ;; 66) root_use - send_stats "원 스톱 튜닝" - echo "원 스톱 시스템 최적화" + send_stats "원스톱 튜닝" + echo "원스톱 시스템 튜닝" echo "------------------------------------------------" - echo "다음은 작동하고 최적화됩니다" - echo "1. 시스템을 최신으로 업데이트하십시오" + echo "다음 콘텐츠가 운영 및 최적화됩니다." + echo "1. 시스템 업데이트 소스를 최적화하고 시스템을 최신 버전으로 업데이트하세요." echo "2. 시스템 정크 파일 정리" - echo -e "3. 가상 메모리를 설정하십시오${gl_huang}1G${gl_bai}" - echo -e "4. SSH 포트 번호를 설정하십시오${gl_huang}5522${gl_bai}" - echo -e "5. 모든 포트를 엽니 다" - echo -e "6. 켜십시오${gl_huang}BBR${gl_bai}가속" - echo -e "7. 시간대를 설정하십시오${gl_huang}상하이${gl_bai}" - echo -e "8. DNS 주소를 자동으로 최적화합니다${gl_huang}해외 : 1.1.1.1 8.8.8.8 국내 : 223.5.5.5${gl_bai}" - echo -e "9. 기본 도구를 설치하십시오${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10. Linux 시스템에서 커널 매개 변수 최적화로 전환하십시오${gl_huang}균형 최적화 모드${gl_bai}" + echo -e "3. 가상 메모리 설정${gl_huang}1G${gl_bai}" + echo -e "4. SSH 포트 번호를 다음으로 설정합니다.${gl_huang}5522${gl_bai}" + echo -e "5. SSH 무차별 대입 크래킹을 방어하기 위해 fall2ban을 시작하세요." + echo -e "6. 모든 포트를 엽니다" + echo -e "7. 켜다${gl_huang}BBR${gl_bai}가속하다" + echo -e "8. 시간대를 다음으로 설정합니다.${gl_huang}상하이${gl_bai}" + echo -e "9. DNS 주소 자동 최적화${gl_huang}해외: 1.1.1.1 8.8.8.8 국내: 223.5.5.5${gl_bai}" + echo -e "10. 네트워크를 다음으로 설정합니다.${gl_huang}IPv4 우선순위${gl_bai}" + echo -e "11. 기본 도구 설치${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux 시스템 커널 매개변수 최적화가 다음으로 전환됩니다.${gl_huang}균형 잡힌 최적화 모드${gl_bai}" echo "------------------------------------------------" - read -e -p "한 번의 클릭 유지 보수가 있습니까? (Y/N) :" choice + read -e -p "원클릭 유지 관리를 원하시나요? (예/아니요):" choice case "$choice" in [Yy]) clear - send_stats "원 스톱 튜닝 시작" + send_stats "원스톱 튜닝 시작" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10. 시스템을 최신으로 업데이트하십시오" + echo -e "[${gl_lv}OK${gl_bai}] 1/12. 시스템을 최신으로 업데이트하세요" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10. 시스템 정크 파일 정리" + echo -e "[${gl_lv}OK${gl_bai}] 2/12. 시스템 정크 파일 정리" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10. 가상 메모리를 설정합니다${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 3/12. 가상 메모리 설정${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10. SSH 포트 번호를 설정하십시오${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 4/12. SSH 포트 번호를 다음으로 설정합니다.${gl_huang}5522${gl_bai}" + echo "------------------------------------------------" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}] 5/12. SSH 무차별 대입 크래킹을 방어하려면 Fail2ban을 시작하세요." + echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10. 모든 포트를 엽니 다" + echo -e "[${gl_lv}OK${gl_bai}] 6/12. 모든 포트 열기" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10. 열려 있는${gl_huang}BBR${gl_bai}가속" + echo -e "[${gl_lv}OK${gl_bai}] 7/12. 열려 있는${gl_huang}BBR${gl_bai}가속하다" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10. 시간대를 설정하십시오${gl_huang}상하이${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 8/12. 시간대를 다음으로 설정하세요.${gl_huang}상하이${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10. DNS 주소를 자동으로 최적화합니다${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}] 9/12. DNS 주소 자동 최적화${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}] 10/12. 네트워크를 다음으로 설정하세요.${gl_huang}IPv4 우선순위${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10. 기본 도구를 설치하십시오${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 11/12. 기본 도구 설치${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10. Linux 시스템의 커널 매개 변수 최적화" - echo -e "${gl_lv}원 스톱 시스템 튜닝이 완료되었습니다${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 12/12. Linux 시스템 커널 매개변수 최적화" + echo -e "${gl_lv}원스톱 시스템 튜닝이 완료되었습니다${gl_bai}" ;; [Nn]) echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac @@ -11952,7 +14495,7 @@ EOF 99) clear - send_stats "시스템을 다시 시작하십시오" + send_stats "시스템을 다시 시작하세요" server_reboot ;; 100) @@ -11961,39 +14504,39 @@ EOF while true; do clear if grep -q '^ENABLE_STATS="true"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_lv}正在采集数据${gl_bai}" + local status_message="${gl_lv}데이터 수집${gl_bai}" elif grep -q '^ENABLE_STATS="false"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_hui}采集已关闭${gl_bai}" + local status_message="${gl_hui}컬렉션이 닫혔습니다.${gl_bai}" else - local status_message="无法确定的状态" + local status_message="불확실한 상태" fi - echo "개인 정보 및 보안" - echo "스크립트는 사용자 기능에 대한 데이터를 수집하고 스크립트 경험을 최적화하며보다 재미 있고 유용한 기능을 만듭니다." - echo "스크립트 버전 번호, 사용 시간, 시스템 버전, CPU 아키텍처, 기계 국가 및 사용 된 기능의 이름을 수집합니다." + echo "개인 정보 보호 및 보안" + echo "스크립트는 사용자의 기능 사용에 대한 데이터를 수집하고 스크립트 경험을 최적화하며 더 재미 있고 유용한 기능을 만듭니다." + echo "스크립트 버전 번호, 사용 시간, 시스템 버전, CPU 아키텍처, 시스템 국가 및 사용된 기능 이름이 수집됩니다." echo "------------------------------------------------" - echo -e "현재 상태 :$status_message" + echo -e "현재 상태:$status_message" echo "--------------------" - echo "1. 수집을 켭니다" - echo "2. 컬렉션을 닫습니다" + echo "1. 수집 시작" + echo "2. 수집 종료" echo "--------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "--------------------" - read -e -p "선택을 입력하십시오 :" sub_choice + read -e -p "선택사항을 입력하세요:" sub_choice case $sub_choice in 1) cd ~ sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="false"/ENABLE_STATS="true"/' ~/kejilion.sh - echo "수집이 활성화되었습니다" - send_stats "개인 정보 보호 및 보안 컬렉션이 활성화되었습니다" + echo "수집이 시작되었습니다" + send_stats "개인정보 보호 및 보안 수집이 사용 설정되었습니다." ;; 2) cd ~ sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' /usr/local/bin/k sed -i 's/^ENABLE_STATS="true"/ENABLE_STATS="false"/' ~/kejilion.sh - echo "컬렉션이 닫혔습니다" - send_stats "개인 정보 보호 및 보안이 컬렉션을 위해 마감되었습니다" + echo "컬렉션이 닫혔습니다." + send_stats "개인정보 보호 및 보안 수집이 사용 중지되었습니다." ;; *) break @@ -12009,11 +14552,11 @@ EOF 102) clear - send_stats "기술 라이온 스크립트를 제거하십시오" - echo "기술 라이온 스크립트를 제거하십시오" + send_stats "기술 사자 스크립트 제거" + echo "기술 사자 스크립트 제거" echo "------------------------------------------------" - echo "Kejilion 스크립트를 완전히 제거하고 다른 기능에 영향을 미치지 않습니다." - read -e -p "계속할거야? (Y/N) :" choice + echo "kejilion 스크립트는 다른 기능에 영향을 주지 않고 완전히 제거됩니다." + read -e -p "계속하시겠습니까? (예/아니요):" choice case "$choice" in [Yy]) @@ -12021,7 +14564,7 @@ EOF (crontab -l | grep -v "kejilion.sh") | crontab - rm -f /usr/local/bin/k rm ~/kejilion.sh - echo "대본은 제거되었습니다." + echo "스크립트가 제거되었습니다. 안녕!" break_end clear exit @@ -12030,7 +14573,7 @@ EOF echo "취소" ;; *) - echo "잘못된 선택, y 또는 N을 입력하십시오." + echo "선택이 잘못되었습니다. Y 또는 N을 입력하세요." ;; esac ;; @@ -12040,7 +14583,7 @@ EOF ;; *) - echo "잘못된 입력!" + echo "입력이 잘못되었습니다!" ;; esac break_end @@ -12068,177 +14611,177 @@ linux_file() { echo "------------------------" ls --color=auto -x echo "------------------------" - echo "1. 디렉토리를 입력합니다. 2. 디렉토리 만들기 3. 디렉토리 권한 수정 4. 디렉토리 이름 바꾸기" - echo "5. 디렉토리 삭제 6. 이전 메뉴 디렉토리로 돌아갑니다." + echo "1. 디렉터리 입력 2. 디렉터리 생성 3. 디렉터리 권한 수정 4. 디렉터리 이름 바꾸기" + echo "5. 디렉토리 삭제 6. 이전 메뉴 디렉토리로 복귀" echo "------------------------" - echo "11. 파일 만들기 12. 파일 편집 13. 파일 권한 수정 14. 파일 이름 바꾸기" - echo "15. 파일을 삭제하십시오" + echo "11. 파일 생성 12. 파일 편집 13. 파일 권한 수정 14. 파일 이름 바꾸기" + echo "15. 파일 삭제" echo "------------------------" - echo "21. 파일 디렉토리 압축 22. zip 파일 디렉토리 23. 파일 디렉토리 이동 24. 파일 디렉토리 복사" - echo "25. 파일을 다른 서버로 전달합니다" + echo "21. 파일 디렉터리 압축 22. 파일 디렉터리 압축 풀기 23. 파일 디렉터리 이동 24. 파일 디렉터리 복사" + echo "25. 다른 서버로 파일 전송" echo "------------------------" - echo "0. 이전 메뉴로 돌아갑니다" + echo "0. 이전 메뉴로 돌아가기" echo "------------------------" - read -e -p "선택을 입력하십시오 :" Limiting + read -e -p "선택사항을 입력하세요:" Limiting case "$Limiting" in 1) # 进入目录 - read -e -p "디렉토리 이름을 입력하십시오 :" dirname - cd "$dirname" 2>/dev/null || echo "디렉토리에 입력 할 수 없습니다" - send_stats "디렉토리로 이동하십시오" + read -e -p "디렉토리 이름을 입력하십시오:" dirname + cd "$dirname" 2>/dev/null || echo "디렉토리에 들어갈 수 없습니다" + send_stats "디렉토리 입력" ;; 2) # 创建目录 - read -e -p "작성하려면 디렉토리 이름을 입력하십시오." dirname - mkdir -p "$dirname" && echo "디렉토리가 생성되었습니다" || echo "창조가 실패했습니다" - send_stats "디렉토리를 만듭니다" + read -e -p "생성할 디렉터리 이름을 입력하세요." dirname + mkdir -p "$dirname" && echo "디렉터리가 생성되었습니다." || echo "생성 실패" + send_stats "디렉터리 생성" ;; 3) # 修改目录权限 - read -e -p "디렉토리 이름을 입력하십시오 :" dirname - read -e -p "권한을 입력하십시오 (예 : 755) :" perm - chmod "$perm" "$dirname" && echo "권한이 수정되었습니다" || echo "수정이 실패했습니다" - send_stats "디렉토리 권한을 수정하십시오" + read -e -p "디렉토리 이름을 입력하십시오:" dirname + read -e -p "권한을 입력하세요(예: 755):" perm + chmod "$perm" "$dirname" && echo "권한이 수정되었습니다." || echo "수정 실패" + send_stats "디렉터리 권한 수정" ;; 4) # 重命名目录 - read -e -p "현재 디렉토리 이름을 입력하십시오 :" current_name - read -e -p "새 디렉토리 이름을 입력하십시오 :" new_name - mv "$current_name" "$new_name" && echo "디렉토리의 이름이 바뀌 었습니다" || echo "이름 바꾸지 실패했습니다" - send_stats "디렉토리의 이름을 바꿉니다" + read -e -p "현재 디렉터리 이름을 입력하세요." current_name + read -e -p "새 디렉터리 이름을 입력하세요." new_name + mv "$current_name" "$new_name" && echo "디렉터리 이름이 변경되었습니다." || echo "이름 바꾸기 실패" + send_stats "디렉터리 이름 바꾸기" ;; 5) # 删除目录 - read -e -p "삭제하려면 디렉토리 이름을 입력하십시오." dirname - rm -rf "$dirname" && echo "디렉토리가 삭제되었습니다" || echo "삭제가 실패했습니다" + read -e -p "삭제할 디렉터리 이름을 입력하세요:" dirname + rm -rf "$dirname" && echo "디렉터리가 삭제되었습니다." || echo "삭제 실패" send_stats "디렉토리 삭제" ;; 6) # 返回上一级选单目录 cd .. - send_stats "이전 메뉴 디렉토리로 돌아갑니다" + send_stats "이전 메뉴 디렉토리로 돌아가기" ;; 11) # 创建文件 - read -e -p "작성하려면 파일 이름을 입력하십시오." filename - touch "$filename" && echo "생성 된 파일" || echo "창조가 실패했습니다" - send_stats "파일을 만듭니다" + read -e -p "생성할 파일 이름을 입력하세요:" filename + touch "$filename" && echo "파일이 생성되었습니다." || echo "생성 실패" + send_stats "파일 생성" ;; 12) # 编辑文件 - read -e -p "편집 할 파일 이름을 입력하십시오." filename + read -e -p "편집할 파일 이름을 입력하십시오:" filename install nano nano "$filename" send_stats "파일 편집" ;; 13) # 修改文件权限 - read -e -p "파일 이름을 입력하십시오 :" filename - read -e -p "권한을 입력하십시오 (예 : 755) :" perm - chmod "$perm" "$filename" && echo "권한이 수정되었습니다" || echo "수정이 실패했습니다" - send_stats "파일 권한을 수정하십시오" + read -e -p "파일 이름을 입력하세요:" filename + read -e -p "권한을 입력하세요(예: 755):" perm + chmod "$perm" "$filename" && echo "권한이 수정되었습니다." || echo "수정 실패" + send_stats "파일 권한 수정" ;; 14) # 重命名文件 - read -e -p "현재 파일 이름을 입력하십시오 :" current_name - read -e -p "새 파일 이름을 입력하십시오 :" new_name - mv "$current_name" "$new_name" && echo "이름이 바뀌 었습니다" || echo "이름 바꾸지 실패했습니다" - send_stats "파일의 이름을 바꿉니다" + read -e -p "현재 파일 이름을 입력하십시오:" current_name + read -e -p "새 파일 이름을 입력하세요:" new_name + mv "$current_name" "$new_name" && echo "파일 이름이 변경되었습니다." || echo "이름 바꾸기 실패" + send_stats "파일 이름 바꾸기" ;; 15) # 删除文件 - read -e -p "삭제하려면 파일 이름을 입력하십시오." filename - rm -f "$filename" && echo "파일이 삭제되었습니다" || echo "삭제가 실패했습니다" + read -e -p "삭제할 파일 이름을 입력하세요:" filename + rm -f "$filename" && echo "파일이 삭제되었습니다." || echo "삭제 실패" send_stats "파일 삭제" ;; 21) # 压缩文件/目录 - read -e -p "압축 할 파일/디렉토리 이름을 입력하십시오." name + read -e -p "압축할 파일/디렉터리 이름을 입력하십시오:" name install tar - tar -czvf "$name.tar.gz" "$name" && echo "압축$name.tar.gz" || echo "압축이 실패했습니다" - send_stats "압축 파일/디렉토리" + tar -czvf "$name.tar.gz" "$name" && echo "압축$name.tar.gz" || echo "압축 실패" + send_stats "압축된 파일/디렉토리" ;; 22) # 解压文件/目录 - read -e -p "파일 이름 (.tar.gz)을 입력하십시오." filename + read -e -p "추출할 파일 이름(.tar.gz)을 입력하십시오." filename install tar - tar -xzvf "$filename" && echo "압축 압축$filename" || echo "감압이 실패했습니다" - send_stats "압축 파일/디렉토리 해제" + tar -xzvf "$filename" && echo "압축이 풀렸습니다.$filename" || echo "압축 해제 실패" + send_stats "파일/디렉토리 압축 풀기" ;; 23) # 移动文件或目录 - read -e -p "이동하려면 파일 또는 디렉토리 경로를 입력하십시오." src_path + read -e -p "이동할 파일 또는 디렉터리 경로를 입력하세요." src_path if [ ! -e "$src_path" ]; then - echo "오류 : 파일 또는 디렉토리가 존재하지 않습니다." - send_stats "파일 또는 디렉토리를 이동하지 못했습니다 : 파일 또는 디렉토리가 존재하지 않습니다." + echo "오류: 파일 또는 디렉터리가 존재하지 않습니다." + send_stats "파일 또는 디렉터리 이동 실패: 파일 또는 디렉터리가 존재하지 않습니다." continue fi - read -e -p "대상 경로를 입력하십시오 (새 파일 이름 또는 디렉토리 이름 포함) :" dest_path + read -e -p "대상 경로(새 파일 또는 디렉터리 이름 포함)를 입력하세요." dest_path if [ -z "$dest_path" ]; then - echo "오류 : 대상 경로를 입력하십시오." - send_stats "움직이는 파일 또는 디렉토리 실패 : 대상 경로가 지정되지 않았습니다." + echo "오류: 대상 경로를 입력하십시오." + send_stats "파일 또는 디렉터리 이동 실패: 대상 경로가 지정되지 않았습니다." continue fi - mv "$src_path" "$dest_path" && echo "파일 또는 디렉토리가 이동했습니다$dest_path" || echo "파일이나 디렉토리를 이동하지 못했습니다" - send_stats "파일 또는 디렉토리를 이동하십시오" + mv "$src_path" "$dest_path" && echo "파일 또는 디렉토리가 다음으로 이동되었습니다.$dest_path" || echo "파일 또는 디렉터리를 이동하지 못했습니다." + send_stats "파일 또는 디렉터리 이동" ;; 24) # 复制文件目录 - read -e -p "복사 할 파일 또는 디렉토리 경로를 입력하십시오." src_path + read -e -p "복사할 파일 또는 디렉터리 경로를 입력하세요." src_path if [ ! -e "$src_path" ]; then - echo "오류 : 파일 또는 디렉토리가 존재하지 않습니다." - send_stats "파일 또는 디렉토리를 복사하지 못했습니다 : 파일 또는 디렉토리가 존재하지 않습니다." + echo "오류: 파일 또는 디렉터리가 존재하지 않습니다." + send_stats "파일 또는 디렉터리 복사 실패: 파일 또는 디렉터리가 존재하지 않습니다." continue fi - read -e -p "대상 경로를 입력하십시오 (새 파일 이름 또는 디렉토리 이름 포함) :" dest_path + read -e -p "대상 경로(새 파일 또는 디렉터리 이름 포함)를 입력하세요." dest_path if [ -z "$dest_path" ]; then - echo "오류 : 대상 경로를 입력하십시오." - send_stats "파일 또는 디렉토리 복사에 실패 : 지정되지 않은 대상 경로" + echo "오류: 대상 경로를 입력하십시오." + send_stats "파일 또는 디렉터리 복사 실패: 대상 경로가 지정되지 않았습니다." continue fi - # -r 옵션을 사용하여 디렉토리를 재귀 적으로 복사하십시오 - cp -r "$src_path" "$dest_path" && echo "파일 또는 디렉토리가 복사되었습니다$dest_path" || echo "파일이나 디렉토리를 복사하지 못했습니다" - send_stats "파일 또는 디렉토리를 복사하십시오" + # 디렉토리를 반복적으로 복사하려면 -r 옵션을 사용하십시오. + cp -r "$src_path" "$dest_path" && echo "복사된 파일 또는 디렉터리$dest_path" || echo "파일 또는 디렉터리를 복사하지 못했습니다." + send_stats "파일 또는 디렉터리 복사" ;; 25) # 传送文件至远端服务器 - read -e -p "전송할 파일 경로를 입력하십시오." file_to_transfer + read -e -p "전송할 파일 경로를 입력하십시오:" file_to_transfer if [ ! -f "$file_to_transfer" ]; then - echo "오류 : 파일이 존재하지 않습니다." - send_stats "파일을 전송하지 못했습니다 : 파일이 존재하지 않습니다." + echo "오류: 파일이 존재하지 않습니다." + send_stats "파일 전송 실패: 파일이 존재하지 않습니다." continue fi - read -e -p "원격 서버 IP를 입력하십시오 :" remote_ip + read -e -p "원격 서버 IP를 입력하세요:" remote_ip if [ -z "$remote_ip" ]; then - echo "오류 : 원격 서버 IP를 입력하십시오." - send_stats "파일 전송 실패 : 원격 서버 IP가 입력되지 않았습니다" + echo "오류: 원격 서버 IP를 입력하세요." + send_stats "파일 전송 실패: 원격 서버 IP가 입력되지 않았습니다." continue fi - read -e -p "원격 서버 사용자 이름 (기본 루트)을 입력하십시오." remote_user + read -e -p "원격 서버 사용자 이름(기본 루트)을 입력하십시오:" remote_user remote_user=${remote_user:-root} - read -e -p "원격 서버 비밀번호를 입력하십시오 :" -s remote_password + read -e -p "원격 서버 비밀번호를 입력하세요:" -s remote_password echo if [ -z "$remote_password" ]; then - echo "오류 : 원격 서버 비밀번호를 입력하십시오." - send_stats "파일 전송 실패 : 원격 서버 비밀번호를 입력하지 않았습니다" + echo "오류: 원격 서버 비밀번호를 입력하세요." + send_stats "파일 전송 실패: 원격 서버 비밀번호가 입력되지 않았습니다." continue fi - read -e -p "로그인 포트 (기본값 22)를 입력하십시오 :" remote_port + read -e -p "로그인 포트(기본값 22)를 입력하세요." remote_port remote_port=${remote_port:-22} - # 알려진 호스트를위한 오래된 항목을 명확하게합니다 + # 알려진 호스트에 대한 이전 항목 지우기 ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 等待时间 - # SCP를 사용하여 파일을 전송합니다 + # scp를 사용하여 파일 전송 scp -P "$remote_port" -o StrictHostKeyChecking=no "$file_to_transfer" "$remote_user@$remote_ip:/home/" < /dev/null 2>&1 - echo -e "${gl_lv}스크립트는 최신 버전으로 업데이트되었습니다!${gl_huang}v$sh_v_new${gl_bai}" - send_stats "스크립트는 최신입니다$sh_v_new" + echo -e "${gl_lv}스크립트가 최신 버전으로 업데이트되었습니다!${gl_huang}v$sh_v_new${gl_bai}" + send_stats "스크립트가 최신 상태입니다.$sh_v_new" break_end ~/kejilion.sh exit @@ -12536,15 +15137,15 @@ while true; do (crontab -l | grep -v "kejilion.sh") | crontab - # (crontab -l 2>/dev/null; echo "0 2 * * * bash -c \"$SH_Update_task\"") | crontab - (crontab -l 2>/dev/null; echo "$(shuf -i 0-59 -n 1) 2 * * * bash -c \"$SH_Update_task\"") | crontab - - echo -e "${gl_lv}자동 업데이트가 활성화되고 스크립트는 매일 오전 2시에 자동으로 업데이트됩니다!${gl_bai}" - send_stats "자동 스크립트 업데이트를 켜십시오" + echo -e "${gl_lv}자동 업데이트가 켜져 있고 매일 새벽 2시에 스크립트가 자동으로 업데이트됩니다!${gl_bai}" + send_stats "자동 스크립트 업데이트 활성화" break_end ;; 3) clear (crontab -l | grep -v "kejilion.sh") | crontab - - echo -e "${gl_lv}자동 업데이트가 닫힙니다${gl_bai}" - send_stats "스크립트 자동 업데이트를 닫습니다" + echo -e "${gl_lv}자동 업데이트가 꺼졌습니다${gl_bai}" + send_stats "자동 스크립트 업데이트 끄기" break_end ;; *) @@ -12566,8 +15167,8 @@ echo -e "${gl_kjlan}" echo "╦╔═╔═╗ ╦╦╦ ╦╔═╗╔╗╔ ╔═╗╦ ╦" echo "╠╩╗║╣ ║║║ ║║ ║║║║ ╚═╗╠═╣" echo "╩ ╩╚═╝╚╝╩╩═╝╩╚═╝╝╚╝o╚═╝╩ ╩" -echo -e "기술 라이온 스크립트 도구 상자 v$sh_v" -echo -e "명령 줄 입력${gl_huang}k${gl_kjlan}스크립트를 신속하게 시작하십시오${gl_bai}" +echo -e "기술 사자 스크립트 도구 상자 v$sh_v" +echo -e "명령줄 입력${gl_huang}k${gl_kjlan}빠른 시작 스크립트${gl_bai}" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}1. ${gl_bai}시스템 정보 쿼리" echo -e "${gl_kjlan}2. ${gl_bai}시스템 업데이트" @@ -12576,25 +15177,24 @@ echo -e "${gl_kjlan}4. ${gl_bai}기본 도구" echo -e "${gl_kjlan}5. ${gl_bai}BBR 관리" echo -e "${gl_kjlan}6. ${gl_bai}도커 관리" echo -e "${gl_kjlan}7. ${gl_bai}워프 관리" -echo -e "${gl_kjlan}8. ${gl_bai}스크립트 수집 테스트" +echo -e "${gl_kjlan}8. ${gl_bai}테스트 스크립트 수집" echo -e "${gl_kjlan}9. ${gl_bai}Oracle Cloud 스크립트 컬렉션" -echo -e "${gl_huang}10. ${gl_bai}LDNMP 웹 사이트 구축" -echo -e "${gl_kjlan}11. ${gl_bai}응용 프로그램 시장" -echo -e "${gl_kjlan}12. ${gl_bai}백엔드 작업 공간" +echo -e "${gl_huang}10. ${gl_bai}LDNMP 웹사이트 구축" +echo -e "${gl_kjlan}11. ${gl_bai}응용 시장" +echo -e "${gl_kjlan}12. ${gl_bai}백엔드 작업공간" echo -e "${gl_kjlan}13. ${gl_bai}시스템 도구" echo -e "${gl_kjlan}14. ${gl_bai}서버 클러스터 제어" -echo -e "${gl_kjlan}15. ${gl_bai}광고 열" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}Phantom Beast Palu 서버 오프닝 스크립트" +echo -e "${gl_kjlan}15. ${gl_bai}광고 칼럼" +echo -e "${gl_kjlan}16. ${gl_bai}게임 서버 오프닝 스크립트 모음" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}스크립트 업데이트" echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}0. ${gl_bai}종료 스크립트" +echo -e "${gl_kjlan}0. ${gl_bai}스크립트 종료" echo -e "${gl_kjlan}------------------------${gl_bai}" -read -e -p "선택을 입력하십시오 :" choice +read -e -p "선택사항을 입력하세요:" choice case $choice in - 1) linux_ps ;; + 1) linux_info ;; 2) clear ; send_stats "시스템 업데이트" ; linux_update ;; 3) clear ; send_stats "시스템 정리" ; linux_clean ;; 4) linux_tools ;; @@ -12611,13 +15211,10 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "Phantom Beast Palu 서버 오프닝 스크립트" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; - *) echo "잘못된 입력!" ;; + *) echo "입력이 잘못되었습니다!" ;; esac break_end done @@ -12625,67 +15222,72 @@ done k_info() { -send_stats "K 명령 참조 사용 사례" +send_stats "k 명령 참조 예" echo "-------------------" -echo "비디오 소개 : https://www.bilibili.com/video/bv1ib421e7it?t=0.1" -echo "다음은 K 명령 참조 유스 케이스입니다." -echo "스크립트 시작 k" -echo "소프트웨어 패키지 설치 K 설치 나노 wget | K 추가 나노 wget | K Nano wget을 설치하십시오" -echo "패키지 k 제거 나노 wget | K del nano wget | k 제거 나노 wget | K를 제거하십시오" -echo "업데이트 시스템 K 업데이트 | K 업데이트" -echo "깨끗한 시스템 쓰레기 K Clean | K 청소" -echo "시스템 패널 k dd |를 다시 설치하십시오 K 재설치" -echo "BBR3 제어판 K BBR3 | K bbrv3" -echo "커널 튜닝 패널 K nhyh | K 커널 최적화" -echo "가상 메모리 K 스왑 2048을 설정하십시오" -echo "가상 시간대 k 시간 아시아/상하이 설정 | k 시내 아시아/상하이" -echo "시스템 재활용 빈 K 쓰레기 | K hsz | K 재활용 빈" -echo "시스템 백업 기능 K 백업 | K bf | K 백업" -echo "SSH 원격 연결 도구 K SSH | K 원격 연결" -echo "rsync 원격 동기화 도구 K rsync | K 원격 동기화" -echo "하드 디스크 관리 도구 K 디스크 | K 하드 디스크 관리" -echo "인트라넷 침투 (서버 측) K frps" -echo "인트라넷 침투 (클라이언트) K frpc" -echo "소프트웨어 시작 K 시작 SSHD | K 시작 SSHD" -echo "소프트웨어 중지 K 중지 SSHD | K 중지 SSHD" -echo "소프트웨어 재시작 K 재시작 SSHD | K는 sshd를 다시 시작합니다" -echo "소프트웨어 상태보기 K 상태 SSHD | K 상태 SSHD" -echo "소프트웨어 부트 K 활성화 Docker | K autostart docke | K 스타트 업 Docker" -echo "도메인 이름 인증서 응용 프로그램 K SSL" -echo "도메인 이름 인증서 만료 쿼리 K SSL PS" -echo "도커 환경 설치 K 도커 설치 | K 도커 설치" -echo "도커 컨테이너 관리 K 도커 PS | K 도커 컨테이너" -echo "Docker Image Management K Docker img | K Docker Image" -echo "LDNMP 사이트 관리 K 웹" -echo "LDNMP 캐시 정리 K 웹 캐시" -echo "WordPress k wp | K WordPress | k wp xxx.com을 설치하십시오" -echo "리버스 프록시 k fd | k rp | k an-generation | k fd xxx.com을 설치하십시오." -echo "로드 밸런싱 k loadbalance | k로드 밸런싱을 설치하십시오" -echo "방화벽 패널 K FHQ | K 방화벽" -echo "포트 k dkdk 8080 | k 오픈 포트 8080" -echo "포트 K GBDK 7800 | K 닫기 포트 7800" -echo "IP K FXIP 127.0.0.0/8 | K 릴리스 IP 127.0.0.0/8 릴리스" -echo "블록 IP K ZZIP 177.5.25.36 | K 블록 IP 177.5.25.36" - - +echo "영상 소개: https://www.bilibili.com/video/BV1ib421E7it?t=0.1" +echo "다음은 k 명령의 참조 사용 사례입니다." +echo "시작 스크립트 k" +echo "패키지 설치 k install nano wget | k 나노 wget 추가 | k는 nano wget을 설치합니다." +echo "패키지 제거 k 제거 nano wget | k 델 나노 wget | k 나노 wget 제거 | k 나노 wget 제거" +echo "시스템 k 업데이트 업데이트 | k 업데이트" +echo "클린 시스템 정크 k 클린 | 케이 깨끗하다" +echo "시스템 패널을 다시 설치하십시오. k dd | k 다시 설치하다" +echo "bbr3 제어판 k bbr3 | kbbrv3" +echo "커널 튜닝 패널 k nhyh | k 커널 최적화" +echo "가상 메모리 k 스왑 2048 설정" +echo "가상 시간대 설정 k 시간 아시아/상하이 | k 시간대 아시아/상하이" +echo "시스템 휴지통 k 쓰레기 | khsz | k 휴지통" +echo "시스템 백업 기능 k 백업 | k bf | k 백업" +echo "SSH 원격 연결 도구 k SSH | k 원격 연결" +echo "rsync 원격 동기화 도구 k rsync | k 원격 동기화" +echo "하드 디스크 관리 도구 k 디스크 | k 하드 디스크 관리" +echo "인트라넷 침투(서버) k frps" +echo "인트라넷 침투(클라이언트) k frpc" +echo "소프트웨어 시작 k start sshd | k sshd를 시작하세요" +echo "소프트웨어 중지 k 중지 sshd | k sshd 중지" +echo "소프트웨어 재시작 k 재시작 sshd | k sshd를 다시 시작하세요" +echo "소프트웨어 상태 확인 k status sshd | k 상태 sshd" +echo "k 도커 활성화 | k 자동 시작 도커 | k 소프트웨어를 부팅할 때 도커를 활성화합니다." +echo "도메인 이름 인증서 신청 k SSL" +echo "도메인 이름 인증서 만료 쿼리 k SSL ps" +echo "도커 관리 플레인 k 도커" +echo "docker 환경 설치 k docker 설치 |k docker 설치" +echo "도커 컨테이너 관리 k 도커 ps |k 도커 컨테이너" +echo "도커 이미지 관리 k docker img |k 도커 이미지" +echo "LDNMP 사이트 관리 k web" +echo "LDNMP 캐시 정리 k 웹 캐시" +echo "WordPress k wp 설치 | k 워드프레스 | k wp xxx.com" +echo "역방향 프록시 설치 k fd |k rp |k 역방향 프록시 |k fd xxx.com" +echo "로드 밸런싱 설치 k loadbalance |k 로드 밸런싱" +echo "L4 로드 밸런싱 설치 k 스트림 |k L4 로드 밸런싱" +echo "방화벽 패널 k fhq |k 방화벽" +echo "포트 k 열기 DKdk 8080 |k 포트 8080 열기" +echo "k 포트 닫기 gbdk 7800 |k 포트 7800 닫기" +echo "릴리스 IP k fxip 127.0.0.0/8 |k 릴리스 IP 127.0.0.0/8" +echo "IP 차단 k zzip 177.5.25.36 |k IP 177.5.25.36 차단" +echo "명령 즐겨찾기 k 즐겨찾기 | k 명령 즐겨찾기" +echo "애플리케이션 시장 관리 k app" +echo "신청번호의 빠른 관리 k app 26 | k 앱 1패널 | k 앱 npm" +echo "Fail2ban 관리 k Fail2ban | 케이 F2B" +echo "시스템 정보 표시 k 정보" } if [ "$#" -eq 0 ]; then - # 매개 변수가없는 경우 대화식 로직을 실행하십시오 + # 인수 없이 대화형 논리를 실행합니다. kejilion_sh else - # 매개 변수가있는 경우 해당 함수를 실행하십시오 + # 매개변수가 있으면 해당 함수를 실행합니다. case $1 in install|add|安装) shift - send_stats "소프트웨어를 설치하십시오" + send_stats "소프트웨어 설치" install "$@" ;; remove|del|uninstall|卸载) shift - send_stats "소프트웨어를 제거하십시오" + send_stats "소프트웨어 제거" remove "$@" ;; update|更新) @@ -12719,7 +15321,7 @@ else rsync_run) shift - send_stats "시간이 정한 RSYNC 동기화" + send_stats "예약된 rsync 동기화" run_task "$@" ;; @@ -12738,7 +15340,7 @@ else find_container_by_host_port "$port" if [ -z "$docker_name" ]; then close_port "$port" - echo "IP+ 포트는 서비스에 액세스하는 것이 차단되었습니다" + echo "IP+포트가 서비스 접근을 차단했습니다." else ip_address block_container_port "$docker_name" "$ipv4_address" @@ -12749,15 +15351,20 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift - send_stats "가상 메모리를 신속하게 설정했습니다" + send_stats "가상 메모리를 빠르게 설정하세요" add_swap "$@" ;; time|时区) shift - send_stats "시간대를 빠르게 설정하십시오" + send_stats "시간대를 빠르게 설정" set_timedate "$@" ;; @@ -12799,9 +15406,13 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift - send_stats "소프트웨어 상태보기" + send_stats "소프트웨어 상태 확인" status "$@" ;; start|启动) @@ -12811,7 +15422,7 @@ else ;; stop|停止) shift - send_stats "소프트웨어 일시 정지" + send_stats "소프트웨어 일시 중지" stop "$@" ;; restart|重启) @@ -12822,21 +15433,21 @@ else enable|autostart|开机启动) shift - send_stats "소프트웨어 부츠" + send_stats "부팅 시 소프트웨어가 자동으로 시작됩니다." enable "$@" ;; ssl) shift if [ "$1" = "ps" ]; then - send_stats "인증서 상태를 확인하십시오" + send_stats "인증서 상태 보기" ssl_ps elif [ -z "$1" ]; then add_ssl - send_stats "인증서를 신속하게 신청하십시오" + send_stats "빨리 자격증 신청하세요" elif [ -n "$1" ]; then add_ssl "$1" - send_stats "인증서를 신속하게 신청하십시오" + send_stats "빨리 자격증 신청하세요" else k_info fi @@ -12846,7 +15457,7 @@ else shift case $1 in install|安装) - send_stats "Docker를 신속하게 설치하십시오" + send_stats "도커를 빠르게 설치하세요" install_docker ;; ps|容器) @@ -12854,11 +15465,11 @@ else docker_ps ;; img|镜像) - send_stats "빠른 미러 관리" + send_stats "빠른 이미지 관리" docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -12878,6 +15489,22 @@ else fi ;; + + app) + shift + send_stats "신청$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/mc.sh b/mc.sh new file mode 100644 index 000000000..b622b4b6f --- /dev/null +++ b/mc.sh @@ -0,0 +1,442 @@ +#!/bin/bash +ln -sf ~/mc.sh /usr/local/bin/mcs + +ip_address() { + # 检测 IPv4 地址 + ipv4_address=$(curl -s --connect-timeout 5 ipv4.ip.sb 2>/dev/null || echo "") + # 检测 IPv6 地址 + ipv6_address=$(curl -s --connect-timeout 5 ipv6.ip.sb 2>/dev/null || echo "") + + # 设置显示变量 + if [ -n "$ipv4_address" ] && [ -n "$ipv6_address" ]; then + ip_display="\033[93m IPv4: $ipv4_address:25565 IPv6: $ipv6_address:25565 \033[0m" + elif [ -n "$ipv4_address" ]; then + ip_display="\033[93m IPv4: $ipv4_address:25565 \033[0m" + elif [ -n "$ipv6_address" ]; then + ip_display="\033[93m IPv6: $ipv6_address:25565 \033[0m" + else + ip_display="\033[93m 无法获取IP地址 \033[0m" + fi +} + + +install() { + if [ $# -eq 0 ]; then + echo "未提供软件包参数!" + return 1 + fi + + for package in "$@"; do + if ! command -v "$package" &>/dev/null; then + if command -v apt &>/dev/null; then + apt update -y && apt install -y "$package" + elif command -v yum &>/dev/null; then + yum -y update && yum -y install "$package" + elif command -v apk &>/dev/null; then + apk update && apk add "$package" + else + echo "未知的包管理器!" + return 1 + fi + fi + done + + return 0 +} + + +remove() { + if [ $# -eq 0 ]; then + echo "未提供软件包参数!" + return 1 + fi + + for package in "$@"; do + if command -v apt &>/dev/null; then + apt purge -y "$package" + elif command -v yum &>/dev/null; then + yum remove -y "$package" + elif command -v apk &>/dev/null; then + apk del "$package" + else + echo "未知的包管理器!" + return 1 + fi + done + + return 0 +} + + +break_end() { + echo -e "\033[0;32m操作完成\033[0m" + echo "按任意键继续..." + read -n 1 -s -r -p "" + echo "" + clear +} + +mc() { + p + exit +} + + +install_add_docker() { + if [ -f "/etc/alpine-release" ]; then + apk update + apk add docker docker-compose + rc-update add docker default + service docker start + else + curl -fsSL https://get.docker.com | sh && ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin + systemctl start docker + systemctl enable docker + fi +} + +install_docker() { + if ! command -v docker &>/dev/null; then + install_add_docker + else + echo "Docker 已经安装" + fi +} + +mc_start() { + ip_address + docker start mcserver > /dev/null 2>&1 + echo -e "\033[0;32mMinecraft服务启动啦!\033[0m" + echo -e "\033[0;32m游戏下载地址: https://www.xbox.com/zh-cn/games/store/minecraft-java-bedrock-edition-for-pc/9nxp44l49shj\033[0m" + echo -e "\033[0;32m进入游戏连接:$ip_display\033[0;32m开始冒险吧!\033[0m" + +} + +mc_backup() { + cd ~ + curl -sS -O https://kejilion.pro/mc_backup.sh && chmod +x mc_backup.sh +} + +mc_install_status() { + CONTAINER_NAME="mcserver" + + # 检查容器是否已安装 + if [ "$(docker ps -a -q -f name=$CONTAINER_NAME 2>/dev/null)" ]; then + container_status="\e[32mMinecraft服务已安装\e[0m" # 绿色 + else + container_status="\e[90mMinecraft服务未安装\e[0m" # 灰色 + fi + + ip_address + # 检查 Docker 容器是否正在运行 + if docker ps --format "table {{.Names}}" | grep -q "^$CONTAINER_NAME$"; then + tmux_status="\e[32m已开服:$ip_display\e[0m" # 绿色 + else + tmux_status="\e[90m未开服\e[0m" # 灰色 + fi + +} + +while true; do +clear +mc_install_status +echo -e "\033[92m███╗ ███╗██╗███╗ ██╗███████╗ ██████╗██████╗ █████╗ ███████╗████████╗\033[0m" +echo -e "\033[92m████╗ ████║██║████╗ ██║██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝╚══██╔══╝\033[0m" +echo -e "\033[92m██╔████╔██║██║██╔██╗ ██║█████╗ ██║ ██████╔╝███████║█████╗ ██║ \033[0m" +echo -e "\033[92m██║╚██╔╝██║██║██║╚██╗██║██╔══╝ ██║ ██╔══██╗██╔══██║██╔══╝ ██║ \033[0m" +echo -e "\033[92m██║ ╚═╝ ██║██║██║ ╚████║███████╗╚██████╗██║ ██║██║ ██║██║ ██║ \033[0m" +echo -e "\033[92m╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ \033[0m" +echo -e "\033[92mMinecraft开服一键脚本工具v1.0.1 by AkarinLiu\033[0m" +echo -e "\033[92m-输入\033[92mmcs\033[92m可快速启动此脚本-\033[0m" +echo -e "$container_status $tmux_status" +echo "------------------------" +echo "1. 安装Minecraft服务" +echo "2. 开启Minecraft服务" +echo "3. 关闭Minecraft服务" +echo "4. 重启Minecraft服务" +echo "------------------------" +echo "5. 查看服务器状态" +echo "6. 设置虚拟内存" +echo "------------------------" +echo "7. 导出游戏存档" +echo "8. 导入游戏存档" +echo "9. 定时备份游戏存档" +echo "------------------------" +echo "10. 修改游戏配置" +echo "o. 添加管理员权限" +echo "p. 删除管理员权限" +echo "------------------------" +echo "11. 更新Minecraft服务" +echo "12. 卸载Minecraft服务" +echo "------------------------" +echo "k. 科技lion脚本工具箱" +echo "------------------------" +echo "00. 脚本更新" +echo "------------------------" +echo "0. 退出脚本" +echo "------------------------" +read -p "请输入你的选择: " choice + +case $choice in + 1) + clear + install_docker + docker run -d --name mcserver -p 25565:25565/tcp --restart=always -e EULA=true -e CREATE_CONSOLE_IN_PIPE=true -v mcserver:/data:rw itzg/minecraft-server + clear + mc_start + ;; + + 2) + clear + docker start $CONTAINER_NAME > /dev/null 2>&1 + mc_start + ;; + + 3) + clear + docker stop $CONTAINER_NAME > /dev/null 2>&1 + echo -e "\033[0;32mMinecraft服务已关闭\033[0m" + ;; + + 4) + clear + docker restart $CONTAINER_NAME > /dev/null 2>&1 + mc_start + ;; + + 5) + clear + install btop + clear + btop + ;; + + 6) + clear + swap_used=$(free -m | awk 'NR==3{print $3}') + swap_total=$(free -m | awk 'NR==3{print $2}') + + if [ "$swap_total" -eq 0 ]; then + swap_percentage=0 + else + swap_percentage=$((swap_used * 100 / swap_total)) + fi + + swap_info="${swap_used}MB/${swap_total}MB (${swap_percentage}%)" + + echo "当前虚拟内存: $swap_info" + + read -p "是否调整大小?(Y/N): " choice + + case "$choice" in + [Yy]) + # 输入新的虚拟内存大小 + read -p "请输入虚拟内存大小MB: " new_swap + + # 获取当前系统中所有的 swap 分区 + swap_partitions=$(grep -E '^/dev/' /proc/swaps | awk '{print $1}') + + # 遍历并删除所有的 swap 分区 + for partition in $swap_partitions; do + swapoff "$partition" + wipefs -a "$partition" # 清除文件系统标识符 + mkswap -f "$partition" + echo "已删除并重新创建 swap 分区: $partition" + done + + # 确保 /swapfile 不再被使用 + swapoff /swapfile + + # 删除旧的 /swapfile + rm -f /swapfile + + # 创建新的 swap 分区 + dd if=/dev/zero of=/swapfile bs=1M count=$new_swap + chmod 600 /swapfile + mkswap /swapfile + swapon /swapfile + + if [ -f /etc/alpine-release ]; then + echo "/swapfile swap swap defaults 0 0" >> /etc/fstab + echo "nohup swapon /swapfile" >> /etc/local.d/swap.start + chmod +x /etc/local.d/swap.start + rc-update add local + else + echo "/swapfile swap swap defaults 0 0" >> /etc/fstab + fi + + echo "虚拟内存大小已调整为${new_swap}MB" + ;; + [Nn]) + echo "已取消" + ;; + *) + echo "无效的选择,请输入 Y 或 N。" + ;; + esac + ;; + + 7) + clear + mkdir -p /home/game + docker cp $CONTAINER_NAME:/data/world /home/game/mc/ > /dev/null 2>&1 + cd /home/game && tar czvf mcsave_$(date +"%Y%m%d%H%M%S").tar.gz mc > /dev/null 2>&1 + rm -rf /home/game/mc/ + echo -e "\033[0;32m游戏存档已导出存放在: /home/game/mc/\033[0m" + ;; + 8) + clear + docker stop mcserver > /dev/null 2>&1 + docker exec -it mcserver bash -c "rm -rf /data/world/*" + cd /home/game/ && ls -t /home/game/mc/*.tar.gz | head -1 | xargs -I {} tar -xzf {} + docker cp /home/game/mc/world/* mcserver:/data/world + rm -rf /home/game/mc/ + echo -e "\033[0;32m游戏存档已导入\033[0m" + docker restart mcserver > /dev/null 2>&1 + mc_start + ;; + + 9) + clear + echo "Minecraft游戏存档定时备份" + echo "------------------------" + echo "1. 每周备份 2. 每天备份 3. 每小时备份" + echo "------------------------" + read -p "请输入你的选择: " dingshi + case $dingshi in + 1) + mc_backup + (crontab -l ; echo "0 0 * * 1 ./mc_backup.sh") | crontab - > /dev/null 2>&1 + echo "每周一备份,已设置" + + ;; + 2) + mc_backup + (crontab -l ; echo "0 3 * * * ./mc_backup.sh") | crontab - > /dev/null 2>&1 + echo "每天凌晨3点备份,已设置" + + ;; + 3) + mc_backup + (crontab -l ; echo "0 * * * * ./mc_backup.sh") | crontab - > /dev/null 2>&1 + echo "每小时整点备份,已设置" + + ;; + *) + echo "已取消" + ;; + esac + ;; + + 10) + clear + echo "配置游戏参数" + echo "------------------------" + read -p "设置游戏难度: (0.和平 1. 简单 2. 普通 3. 困难):" Difficulty + case $Difficulty in + 0) + docker exec --user 1000 mcserver mc-send-to-console difficulty peaceful + ;; + 1) + docker exec --user 1000 mcserver mc-send-to-console difficulty easy + ;; + + 2) + docker exec --user 1000 mcserver mc-send-to-console difficulty normal + ;; + 3) + docker exec --user 1000 mcserver mc-send-to-console difficulty hard + ;; + *) + echo "-默认设置为普通难度" + docker exec --user 1000 mcserver mc-send-to-console difficulty normal + ;; + esac + + read -p "死亡后掉落设置: (1. 掉落 2. 不掉落):" DeathPenalty + case $DeathPenalty in + 1) + docker exec --user 1000 mcserver mc-send-to-console gamerule KeepInventoy false + ;; + + 2) + docker exec --user 1000 mcserver mc-send-to-console gamerule KeepInventoy true + ;; + *) + docker exec --user 1000 mcserver mc-send-to-console gamerule KeepInventoy false + echo "-默认设置为掉落" + ;; + esac + + read -p "设置pvp模式: (1. 开启 2. 关闭):" mc_pvp + + case $mc_pvp in + 1) + docker exec --user 1000 mcserver mc-send-to-console gamerule pvp true + ;; + 2) + docker exec --user 1000 mcserver mc-send-to-console gamerule pvp false + ;; + *) + docker exec --user 1000 mcserver mc-send-to-console gamerule pvp false + echo "-默认关闭pvp模式" + ;; + esac + + # 更新配置 + echo -e "\033[0;32m游戏配置已更改\033[0m" + ;; + + + 11) + clear + docker stop mcserver > /dev/null 2>&1 + docker restart mcserver > /dev/null 2>&1 + docker exec -it mcserver bash -c "/home/steam/mcserver/mcserver.sh +login anonymous +app_update 2394010 validate +quit" + clear + echo -e "\033[0;32mMinecraft已更新\033[0m" + mc_start + ;; + + 12) + clear + docker rm -f mcserver + docker rmi -f itzg/minecraft-server + ;; + o) + read -p "请输入 Minecraft Java 版档案名称:" mc_op + docker exec --user 1000 mcserver mc-send-to-console op $mc_op + ;; + p) + read -p "请输入 Minecraft Java 版档案名称:" mc_deop + docker exec --user 1000 mcserver mc-send-to-console deop $mc_deop + ;; + k) + cd ~ + curl -sS -O https://kejilion.pro/kejilion.sh && chmod +x kejilion.sh && ./kejilion.sh + exit + ;; + + 00) + cd ~ + curl -sS -O https://kejilion.pro/mc_log.sh && chmod +x mc_log.sh && ./mc_log.sh + rm mc_log.sh + echo "" + curl -sS -O https://kejilion.pro/mc.sh && chmod +x mc.sh + echo "脚本已更新到最新版本!" + break_end + mc + ;; + + + 0) + clear + exit + ;; + + *) + echo "无效的输入!" + ;; +esac + break_end +done diff --git a/mc_backup.sh b/mc_backup.sh new file mode 100644 index 000000000..a996cc18d --- /dev/null +++ b/mc_backup.sh @@ -0,0 +1,7 @@ +#!/bin/bash +clear +mkdir -p /home/game +docker cp mcserver:/data /home/game/mc +cd /home/game/mc && tar czvf mc_$(date +"%Y%m%d%H%M%S").tar.gz mc +rm -rf /home/game/mc/ +echo -e "\033[0;32m游戏存档已导出存放在: /home/game/mc/\033[0m" diff --git a/mc_log.sh b/mc_log.sh new file mode 100644 index 000000000..0023e118d --- /dev/null +++ b/mc_log.sh @@ -0,0 +1,7 @@ + clear + echo "脚本更新日志" + echo "------------------------" + echo "2025-11-16 v1.0.1" + echo "Minecraft 开服脚本魔改自 幻兽帕鲁开服脚本" + echo "2025-11-17 v1.0.1" + ech "对 Minecraft 的难度等细节进行了适配" diff --git a/optimized_php.ini b/optimized_php.ini index e1a3531da..dfb2e0a75 100644 --- a/optimized_php.ini +++ b/optimized_php.ini @@ -5,7 +5,7 @@ error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_DEPRECATED expose_php = Off allow_url_fopen = Off allow_url_include = Off -disable_functions = exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source +disable_functions = passthru,system,proc_open,popen,parse_ini_file,show_source default_charset = "UTF-8" session.cookie_httponly = 1 @@ -13,6 +13,7 @@ session.cookie_secure = 1 session.use_strict_mode = 1 session.use_only_cookies = 1 + ; Opcache配置 opcache.enable=1 opcache.enable_cli=1 @@ -28,6 +29,7 @@ opcache.max_wasted_percentage=5 opcache.jit=tracing opcache.jit_buffer_size=64M + ; Realpath Cache配置 realpath_cache_size=4096k realpath_cache_ttl=3600 diff --git a/translate.py b/translate.py index 08fa7e575..96c5ae508 100644 --- a/translate.py +++ b/translate.py @@ -9,94 +9,84 @@ def is_chinese(text): return bool(re.search(r'[\u4e00-\u9fff]', text)) def translate_text(text, target_lang): + if not text.strip() or not is_chinese(text): + return text try: - return GoogleTranslator(source='zh-CN', target=target_lang).translate(text) + # 过滤掉一些不该翻译的特殊符号 + clean_text = text.strip() + result = GoogleTranslator(source='zh-CN', target=target_lang).translate(clean_text) + return result except Exception as e: - print(f"\nTranslation error: {e}") + print(f"\n[Error] {e}") return text -def translate_line_preserving_variables(line, target_lang): +def process_content_with_vars(content, target_lang): """ - Translate only Chinese parts in echo/read/send_stats commands, excluding shell variables + 核心逻辑:保护 ${var} 和 $var,翻译其中的中文部分 """ - # Match double or single quoted strings - def repl(match): - full_string = match.group(0) - quote = full_string[0] - content = full_string[1:-1] - # Split by variable expressions - parts = re.split(r'(\$\{?\w+\}?)', content) - translated_parts = [ - translate_text(p, target_lang) if is_chinese(p) else p - for p in parts - ] - return quote + ''.join(translated_parts) + quote - - return re.sub(r'(?:\'[^\']*\'|"[^"]*")', repl, line) + # 匹配 ${var} 或 $var (字母数字下划线) + parts = re.split(r'(\$\{\w+\}|\$\w+)', content) + translated_parts = [] + for p in parts: + if p.startswith('$'): # 变量部分,保持原样 + translated_parts.append(p) + elif is_chinese(p): # 中文部分,翻译 + translated_parts.append(translate_text(p, target_lang)) + else: # 其他英文/符号,保持原样 + translated_parts.append(p) + return "".join(translated_parts) + +def universal_translator(line, target_lang): + """ + 通用翻译引擎:识别行内所有引号内容并翻译 + """ + # 1. 保护注释行 + leading_space = re.match(r'^(\s*)', line).group(1) + stripped = line.strip() + if stripped.startswith('#'): + comment_content = stripped[1:].strip() + if is_chinese(comment_content): + return f"{leading_space}# {translate_text(comment_content, target_lang)}\n" + return line + + # 2. 识别所有引号内的内容 (双引号或单引号) + # 使用正则匹配引号对,同时处理转义引号 \" + def replacer(match): + quote_type = match.group(1) # ' 或 " + content = match.group(2) # 引号内的文本内容 + if is_chinese(content): + # 翻译内容,但保护里面的变量 + translated = process_content_with_vars(content, target_lang) + return f"{quote_type}{translated}{quote_type}" + return match.group(0) + + # 匹配 "content" 或 'content' + new_line = re.sub(r'([\'"])(.*?)(? Google翻译语言代码 - languages = { - 'en': 'en', # 英语 - 'tw': 'zh-TW', # 繁体中文 - 'kr': 'ko', # 韩语 - 'jp': 'ja' # 日语 - } - - success_count = 0 - - for dir_name, lang_code in languages.items(): - output_file = f'{dir_name}/kejilion.sh' - if translate_file(input_file, output_file, lang_code): - success_count += 1 - print(f"✓ Successfully translated to {dir_name}") - else: - print(f"✗ Failed to translate to {dir_name}") - print("-" * 50) - - print(f"\nTranslation summary: {success_count}/{len(languages)} languages completed") - - if success_count == 0: - sys.exit(1) + langs = {'en': 'en', 'tw': 'zh-TW', 'kr': 'ko', 'jp': 'ja'} + for dir_name, lang_code in langs.items(): + translate_file(input_file, f'{dir_name}/kejilion.sh', lang_code) diff --git a/tw/kejilion.sh b/tw/kejilion.sh index 6d28b8d24..8f711cf7e 100644 --- a/tw/kejilion.sh +++ b/tw/kejilion.sh @@ -1,5 +1,5 @@ #!/bin/bash -sh_v="4.0.3" +sh_v="4.3.1" gl_hui='\e[37m' @@ -154,7 +154,7 @@ public_ip=$(get_public_ip) isp_info=$(curl -s --max-time 3 http://ipinfo.io/org) -if echo "$isp_info" | grep -Eiq 'china|mobile|unicom|telecom'; then +if echo "$isp_info" | grep -Eiq 'mobile|unicom|telecom'; then ipv4_address=$(get_local_ip) else ipv4_address="$public_ip" @@ -213,12 +213,15 @@ install() { check_disk_space() { + local required_gb=$1 + local path=${2:-/} - required_gb=$1 - required_space_mb=$((required_gb * 1024)) - available_space_mb=$(df -m / | awk 'NR==2 {print $4}') + mkdir -p "$path" - if [ $available_space_mb -lt $required_space_mb ]; then + local required_space_mb=$((required_gb * 1024)) + local available_space_mb=$(df -m "$path" | awk 'NR==2 {print $4}') + + if [ "$available_space_mb" -lt "$required_space_mb" ]; then echo -e "${gl_huang}提示:${gl_bai}磁盤空間不足!" echo "當前可用空間: $((available_space_mb/1024))G" echo "最小需求空間:${required_gb}G" @@ -230,8 +233,15 @@ check_disk_space() { } + install_dependency() { + switch_mirror false false + check_port + check_swap + prefer_ipv4 + auto_optimize_dns install wget unzip tar jq grep + } remove() { @@ -349,22 +359,22 @@ kejilion() { -check_port() { - install lsof +stop_containers_or_kill_process() { + local port=$1 + local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) - stop_containers_or_kill_process() { - local port=$1 - local containers=$(docker ps --filter "publish=$port" --format "{{.ID}}" 2>/dev/null) + if [ -n "$containers" ]; then + docker stop $containers + else + install lsof + for pid in $(lsof -t -i:$port); do + kill -9 $pid + done + fi +} - if [ -n "$containers" ]; then - docker stop $containers - else - for pid in $(lsof -t -i:$port); do - kill -9 $pid - done - fi - } +check_port() { stop_containers_or_kill_process 80 stop_containers_or_kill_process 443 } @@ -377,23 +387,23 @@ if [ "$country" = "CN" ]; then cat > /etc/docker/daemon.json << EOF { "registry-mirrors": [ - "https://docker-0.unsee.tech", - "https://docker.1panel.live", - "https://registry.dockermirror.com", - "https://docker.imgdb.de", - "https://docker.m.daocloud.io", - "https://hub.firefly.store", - "https://hub.littlediary.cn", + "https://docker.1ms.run", + "https://docker.m.ixdev.cn", "https://hub.rat.dev", - "https://dhub.kubesre.xyz", - "https://cjie.eu.org", - "https://docker.1panelproxy.com", + "https://dockerproxy.net", + "https://docker-registry.nmqu.com", + "https://docker.amingg.com", "https://docker.hlmirror.com", - "https://hub.fast360.xyz", - "https://dockerpull.cn", - "https://cr.laoyou.ip-ddns.com", - "https://docker.melikeme.cn", - "https://docker.kejilion.pro" + "https://hub1.nat.tf", + "https://hub2.nat.tf", + "https://hub3.nat.tf", + "https://docker.m.daocloud.io", + "https://docker.kejilion.pro", + "https://docker.367231.xyz", + "https://hub.1panel.dev", + "https://dockerproxy.cool", + "https://docker.apiba.cn", + "https://proxy.vvvv.ee" ] } EOF @@ -407,18 +417,31 @@ restart docker } -install_add_docker_guanfang() { + +linuxmirrors_install_docker() { + local country=$(curl -s ipinfo.io/country) if [ "$country" = "CN" ]; then - cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/install && chmod +x install - sh install --mirror Aliyun - rm -f install + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source mirrors.huaweicloud.com/docker-ce \ + --source-registry docker.1ms.run \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips else - curl -fsSL https://get.docker.com | sh + bash <(curl -sSL https://linuxmirrors.cn/docker.sh) \ + --source download.docker.com \ + --source-registry registry.hub.docker.com \ + --protocol https \ + --use-intranet-source false \ + --install-latest true \ + --close-firewall false \ + --ignore-backup-tips fi -install_add_docker_cn +install_add_docker_cn } @@ -426,61 +449,8 @@ install_add_docker_cn install_add_docker() { echo -e "${gl_huang}正在安裝docker環境...${gl_bai}" - if [ -f /etc/os-release ] && grep -q "Fedora" /etc/os-release; then - install_add_docker_guanfang - elif command -v dnf &>/dev/null; then - dnf update -y - dnf install -y yum-utils device-mapper-persistent-data lvm2 - rm -f /etc/yum.repos.d/docker*.repo > /dev/null - country=$(curl -s ipinfo.io/country) - arch=$(uname -m) - if [ "$country" = "CN" ]; then - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo | tee /etc/yum.repos.d/docker-ce.repo > /dev/null - else - yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo > /dev/null - fi - dnf install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - elif [ -f /etc/os-release ] && grep -q "Kali" /etc/os-release; then - apt update - apt upgrade -y - apt install -y apt-transport-https ca-certificates curl gnupg lsb-release - rm -f /usr/share/keyrings/docker-archive-keyring.gpg - local country=$(curl -s ipinfo.io/country) - local arch=$(uname -m) - if [ "$country" = "CN" ]; then - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/etc\/apt\/keyrings\/docker-archive-keyring.gpg\] https:\/\/mirrors.aliyun.com\/docker-ce\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - else - if [ "$arch" = "x86_64" ]; then - sed -i '/^deb \[arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - elif [ "$arch" = "aarch64" ]; then - sed -i '/^deb \[arch=arm64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg\] https:\/\/download.docker.com\/linux\/debian bullseye stable/d' /etc/apt/sources.list.d/docker.list > /dev/null - mkdir -p /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg > /dev/null - echo "deb [arch=arm64 signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - fi - fi - apt update - apt install -y docker-ce docker-ce-cli containerd.io - install_add_docker_cn - - - elif command -v apt &>/dev/null || command -v yum &>/dev/null; then - install_add_docker_guanfang + if command -v apt &>/dev/null || command -v yum &>/dev/null || command -v dnf &>/dev/null; then + linuxmirrors_install_docker else install docker docker-compose install_add_docker_cn @@ -576,7 +546,7 @@ while true; do 11) send_stats "進入容器" read -e -p "請輸入容器名:" dockername - docker exec -it $dockername /bin/sh + docker exec $dockername /bin/sh break_end ;; 12) @@ -590,7 +560,7 @@ while true; do echo "" container_ids=$(docker ps -q) echo "------------------------------------------------------------" - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "容器名稱" "網絡名稱" "IP地址" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") local container_name=$(echo "$container_info" | awk '{print $1}') @@ -1025,91 +995,84 @@ disable_ddos_defense() { # 管理國家IP規則的函數 manage_country_rules() { local action="$1" - local country_code="$2" - local ipset_name="${country_code,,}_block" - local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" + shift # 去掉第一个参数,剩下的全是国家代码 install ipset - case "$action" in - block) - # 如果 ipset 不存在則創建 - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + for country_code in "$@"; do + local ipset_name="${country_code,,}_block" + local download_url="http://www.ipdeny.com/ipblocks/data/countries/${country_code,,}.zone" - # 下載 IP 區域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "錯誤:下載$country_code的 IP 區域文件失敗" - exit 1 - fi + case "$action" in + block) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 將 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "錯誤:下載$country_code的 IP 區域文件失敗" + continue + fi - # 使用 iptables 阻止 IP - iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - iptables -I OUTPUT -m set --match-set "$ipset_name" dst -j DROP + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - echo "已成功阻止$country_code的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -I INPUT -m set --match-set "$ipset_name" src -j DROP - allow) - # 為允許的國家創建 ipset(如果不存在) - if ! ipset list "$ipset_name" &> /dev/null; then - ipset create "$ipset_name" hash:net - fi + echo "已成功阻止$country_code的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 下載 IP 區域文件 - if ! wget -q "$download_url" -O "${country_code,,}.zone"; then - echo "錯誤:下載$country_code的 IP 區域文件失敗" - exit 1 - fi + allow) + if ! ipset list "$ipset_name" &> /dev/null; then + ipset create "$ipset_name" hash:net + fi - # 刪除現有的國家規則 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null - ipset flush "$ipset_name" + if ! wget -q "$download_url" -O "${country_code,,}.zone"; then + echo "錯誤:下載$country_code的 IP 區域文件失敗" + continue + fi - # 將 IP 添加到 ipset - while IFS= read -r ip; do - ipset add "$ipset_name" "$ip" - done < "${country_code,,}.zone" + ipset flush "$ipset_name" + while IFS= read -r ip; do + ipset add "$ipset_name" "$ip" 2>/dev/null + done < "${country_code,,}.zone" - # 僅允許指定國家的 IP - iptables -P INPUT DROP - iptables -P OUTPUT DROP - iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - iptables -A OUTPUT -m set --match-set "$ipset_name" dst -j ACCEPT - echo "已成功僅允許$country_code的 IP 地址" - rm "${country_code,,}.zone" - ;; + iptables -P INPUT DROP + iptables -A INPUT -m set --match-set "$ipset_name" src -j ACCEPT - unblock) - # 刪除國家的 iptables 規則 - iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - iptables -D OUTPUT -m set --match-set "$ipset_name" dst -j DROP 2>/dev/null + echo "已成功允許$country_code的 IP 地址" + rm "${country_code,,}.zone" + ;; - # 銷毀 ipset - if ipset list "$ipset_name" &> /dev/null; then - ipset destroy "$ipset_name" - fi + unblock) + iptables -D INPUT -m set --match-set "$ipset_name" src -j DROP 2>/dev/null - echo "已成功解除$country_code的 IP 地址限制" - ;; + if ipset list "$ipset_name" &> /dev/null; then + ipset destroy "$ipset_name" + fi - *) - ;; - esac + echo "已成功解除$country_code的 IP 地址限制" + ;; + + *) + echo "用法: manage_country_rules {block|allow|unblock} " + ;; + esac + done } + + + + + + iptables_panel() { root_use install iptables @@ -1223,18 +1186,18 @@ iptables_panel() { ;; 15) - read -e -p "請輸入阻止的國家代碼(如 CN, US, JP):" country_code + read -e -p "請輸入阻止的國家代碼(多個國家代碼可用空格隔開如 CN US JP):" country_code manage_country_rules block $country_code send_stats "允許國家$country_code的IP" ;; 16) - read -e -p "請輸入允許的國家代碼(如 CN, US, JP):" country_code + read -e -p "請輸入允許的國家代碼(多個國家代碼可用空格隔開如 CN US JP):" country_code manage_country_rules allow $country_code send_stats "阻止國家$country_code的IP" ;; 17) - read -e -p "請輸入清除的國家代碼(如 CN, US, JP):" country_code + read -e -p "請輸入清除的國家代碼(多個國家代碼可用空格隔開如 CN US JP):" country_code manage_country_rules unblock $country_code send_stats "清除國家$country_code的IP" ;; @@ -1252,8 +1215,6 @@ iptables_panel() { - - add_swap() { local new_swap=$1 # 获取传入的参数 @@ -1342,11 +1303,9 @@ ldnmp_v() { install_ldnmp_conf() { # 創建必要的目錄和文件 - cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/redis web/log/nginx && touch web/docker-compose.yml + cd /home && mkdir -p web/html web/mysql web/certs web/conf.d web/stream.d web/redis web/log/nginx && touch web/docker-compose.yml wget -O /home/web/nginx.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/nginx10.conf wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default10.conf - wget -O /home/web/redis/valkey.conf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/valkey.conf - default_server_ssl @@ -1362,31 +1321,69 @@ install_ldnmp_conf() { } +update_docker_compose_with_db_creds() { + cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if ! grep -q "stream" /home/web/docker-compose.yml; then + wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml -install_ldnmp() { + dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') + dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - check_swap + sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml + sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml + fi - cp /home/web/docker-compose.yml /home/web/docker-compose1.yml + if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then + sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 + fi - if ! grep -q "network_mode" /home/web/docker-compose.yml; then - wget -O /home/web/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/LNMP-docker-compose-10.yml - dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbuse=$(grep -oP 'MYSQL_USER:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') - dbusepasswd=$(grep -oP 'MYSQL_PASSWORD:\s*\K.*' /home/web/docker-compose1.yml | tr -d '[:space:]') +} - sed -i "s#webroot#$dbrootpasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilionYYDS#$dbusepasswd#g" /home/web/docker-compose.yml - sed -i "s#kejilion#$dbuse#g" /home/web/docker-compose.yml - fi - if grep -q "kjlion/nginx:alpine" /home/web/docker-compose1.yml; then - sed -i 's|kjlion/nginx:alpine|nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - sed -i 's|nginx:alpine|kjlion/nginx:alpine|g' /home/web/docker-compose.yml > /dev/null 2>&1 - fi + + +auto_optimize_dns() { + # 獲取國家代碼(如 CN、US 等) + local country=$(curl -s ipinfo.io/country) + + # 根據國家設置 DNS + if [ "$country" = "CN" ]; then + local dns1_ipv4="223.5.5.5" + local dns2_ipv4="183.60.83.19" + local dns1_ipv6="2400:3200::1" + local dns2_ipv6="2400:da00::6666" + else + local dns1_ipv4="1.1.1.1" + local dns2_ipv4="8.8.8.8" + local dns1_ipv6="2606:4700:4700::1111" + local dns2_ipv6="2001:4860:4860::8888" + fi + + set_dns + + +} + + +prefer_ipv4() { +grep -q '^precedence ::ffff:0:0/96 100' /etc/gai.conf 2>/dev/null \ + || echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf +echo "已切換為 IPv4 優先" +send_stats "已切換為 IPv4 優先" +} + + + + +install_ldnmp() { + + update_docker_compose_with_db_creds cd /home/web && docker compose up -d sleep 1 @@ -1395,8 +1392,16 @@ install_ldnmp() { fix_phpfpm_conf php fix_phpfpm_conf php74 - restart_ldnmp + # mysql調優 + wget -O /home/custom_mysql_config.cnf ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/custom_mysql_config-1.cnf + docker cp /home/custom_mysql_config.cnf mysql:/etc/mysql/conf.d/ + rm -rf /home/custom_mysql_config.cnf + + + + restart_ldnmp + sleep 2 clear echo "LDNMP環境安裝完畢" @@ -1420,15 +1425,22 @@ install_certbot() { } + + + + + + + install_ssltls() { - docker stop nginx > /dev/null 2>&1 check_port > /dev/null 2>&1 + docker stop nginx > /dev/null 2>&1 cd ~ local file_path="/etc/letsencrypt/live/$yuming/fullchain.pem" if [ ! -f "$file_path" ]; then local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' - local ipv6_pattern='^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))))$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' if [[ ($yuming =~ $ipv4_pattern || $yuming =~ $ipv6_pattern) ]]; then mkdir -p /etc/letsencrypt/live/$yuming/ if command -v dnf &>/dev/null || command -v yum &>/dev/null; then @@ -1438,7 +1450,10 @@ install_ssltls() { openssl req -x509 -key /etc/letsencrypt/live/$yuming/privkey.pem -out /etc/letsencrypt/live/$yuming/fullchain.pem -days 5475 -subj "/C=US/ST=State/L=City/O=Organization/OU=Organizational Unit/CN=Common Name" fi else - docker run -it --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa + if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then + iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT + fi + docker run --rm -p 80:80 -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot certonly --standalone -d "$yuming" --email your@email.com --agree-tos --no-eff-email --force-renewal --key-type ecdsa fi fi mkdir -p /home/web/certs/ @@ -1475,7 +1490,7 @@ if [ -z "$yuming" ]; then fi install_docker install_certbot -docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null +docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status install_ssltls_text @@ -1534,12 +1549,77 @@ certs_status() { echo -e "4. 防火牆限制 ➠ 檢查80/443端口是否開放,確保驗證可訪問" echo -e "5. 申請次數超限 ➠ Let's Encrypt有每週限額(5次/域名/週)" echo -e "6. 國內備案限制 ➠ 中國大陸環境請確認域名是否備案" - break_end - clear - echo "請再次嘗試部署$webname" - add_yuming - install_ssltls - certs_status + echo "------------------------" + echo "1. 重新申請 2. 導入已有證書 3. 不帶證書改用HTTP訪問 0. 退出" + echo "------------------------" + read -e -p "請輸入你的選擇:" sub_choice + case $sub_choice in + 1) + send_stats "重新申請" + echo "請再次嘗試部署$webname" + add_yuming + install_ssltls + certs_status + + ;; + 2) + send_stats "導入已有證書" + + # 定義文件路徑 + local cert_file="/home/web/certs/${yuming}_cert.pem" + local key_file="/home/web/certs/${yuming}_key.pem" + + mkdir -p /home/web/certs + + # 1. 輸入證書 (ECC 和 RSA 證書開頭都是 BEGIN CERTIFICATE) + echo "請粘貼 證書 (CRT/PEM) 內容 (按兩次回車結束):" + local cert_content="" + while IFS= read -r line; do + [[ -z "$line" && "$cert_content" == *"-----BEGIN"* ]] && break + cert_content+="${line}"$'\n' + done + + # 2. 輸入私鑰 (兼容 RSA, ECC, PKCS#8) + echo "請粘貼 證書私鑰 (Private Key) 內容 (按兩次回車結束):" + local key_content="" + while IFS= read -r line; do + [[ -z "$line" && "$key_content" == *"-----BEGIN"* ]] && break + key_content+="${line}"$'\n' + done + + # 3. 智能校驗 + # 只要包含 "BEGIN CERTIFICATE" 和 "PRIVATE KEY" 即可通過 + if [[ "$cert_content" == *"-----BEGIN CERTIFICATE-----"* && "$key_content" == *"PRIVATE KEY-----"* ]]; then + echo -n "$cert_content" > "$cert_file" + echo -n "$key_content" > "$key_file" + + chmod 644 "$cert_file" + chmod 600 "$key_file" + + # 識別當前證書類型並顯示 + if [[ "$key_content" == *"EC PRIVATE KEY"* ]]; then + echo "檢測到 ECC 證書已成功保存。" + else + echo "檢測到 RSA 證書已成功保存。" + fi + auth_method="ssl_imported" + else + echo "錯誤:無效的證書或私鑰格式!" + certs_status + fi + + ;; + 3) + send_stats "不帶證書改用HTTP訪問" + sed -i '/if (\$scheme = http) {/,/}/s/^/#/' /home/web/conf.d/${yuming}.conf + sed -i '/ssl_certificate/d; /ssl_certificate_key/d' /home/web/conf.d/${yuming}.conf + sed -i '/443 ssl/d; /443 quic/d' /home/web/conf.d/${yuming}.conf + ;; + *) + send_stats "退出申請" + exit + ;; + esac fi } @@ -1561,6 +1641,40 @@ add_yuming() { } +check_ip_and_get_access_port() { + local yuming="$1" + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + read -e -p "請輸入訪問/監聽端口,回車默認使用 80:" access_port + access_port=${access_port:-80} + fi +} + + + +update_nginx_listen_port() { + local yuming="$1" + local access_port="$2" + local conf="/home/web/conf.d/${yuming}.conf" + + # 如果 access_port 為空,則跳過 + [ -z "$access_port" ] && return 0 + + # 刪除所有 listen 行 + sed -i '/^[[:space:]]*listen[[:space:]]\+/d' "$conf" + + # 在 server { 後插入新的 l​​isten + sed -i "/server {/a\\ + listen ${access_port};\\ + listen [::]:${access_port}; +" "$conf" +} + + + add_db() { dbname=$(echo "$yuming" | sed -e 's/[^A-Za-z0-9]/_/g') dbname="${dbname}" @@ -1571,28 +1685,8 @@ add_db() { docker exec mysql mysql -u root -p"$dbrootpasswd" -e "CREATE DATABASE $dbname; GRANT ALL PRIVILEGES ON $dbname.* TO \"$dbuse\"@\"%\";" } -reverse_proxy() { - ip_address - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf - sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$ipv4_address/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$duankou|g" /home/web/conf.d/$yuming.conf - nginx_http_on - docker exec nginx nginx -s reload -} - - -restart_redis() { - rm -rf /home/web/redis/* - docker exec redis redis-cli FLUSHALL > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory 1gb > /dev/null 2>&1 - # docker exec -it redis redis-cli CONFIG SET maxmemory-policy allkeys-lru > /dev/null 2>&1 -} - - restart_ldnmp() { - restart_redis docker exec nginx chown -R nginx:nginx /var/www/html > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/proxy > /dev/null 2>&1 docker exec nginx mkdir -p /var/cache/nginx/fastcgi > /dev/null 2>&1 @@ -1600,7 +1694,8 @@ restart_ldnmp() { docker exec nginx chown -R nginx:nginx /var/cache/nginx/fastcgi > /dev/null 2>&1 docker exec php chown -R www-data:www-data /var/www/html > /dev/null 2>&1 docker exec php74 chown -R www-data:www-data /var/www/html > /dev/null 2>&1 - cd /home/web && docker compose restart nginx php php74 + cd /home/web && docker compose restart + } @@ -1635,7 +1730,7 @@ phpmyadmin_upgrade() { cd /home/web/ docker rm -f $ldnmp_pods > /dev/null 2>&1 docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 - curl -sS -O https://raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/docker/refs/heads/main/docker-compose.phpmyadmin.yml docker compose -f docker-compose.phpmyadmin.yml up -d clear ip_address @@ -1694,7 +1789,6 @@ web_cache() { send_stats "清理站點緩存" cf_purge_cache cd /home/web && docker compose restart - restart_redis } @@ -1768,7 +1862,7 @@ check_waf_status() { if grep -q "^\s*#\s*modsecurity on;" /home/web/nginx.conf; then waf_status="" elif grep -q "modsecurity on;" /home/web/nginx.conf; then - waf_status=" WAF已开启" + waf_status="WAF已開啟" else waf_status="" fi @@ -1776,8 +1870,8 @@ check_waf_status() { check_cf_mode() { - if [ -f "/path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf" ]; then - CFmessage=" cf模式已开启" + if [ -f "/etc/fail2ban/action.d/cloudflare-docker.conf" ]; then + CFmessage="cf模式已開啟" else CFmessage="" fi @@ -1847,6 +1941,43 @@ patch_wp_debug() { } + + +patch_wp_url() { + local HOME_URL="$1" + local SITE_URL="$2" + local TARGET_DIR="/home/web/html" + + find "$TARGET_DIR" -type f -name "wp-config-sample.php" | while read -r FILE; do + # 刪除舊定義 + sed -i "/define(['\"]WP_HOME['\"].*/d" "$FILE" + sed -i "/define(['\"]WP_SITEURL['\"].*/d" "$FILE" + + # 生成插入內容 + INSERT=" +define('WP_HOME', '$HOME_URL'); +define('WP_SITEURL', '$SITE_URL'); +" + + # 插入到 “Happy publishing” 之前 + awk -v insert="$INSERT" ' + /Happy publishing/ { + print insert + } + { print } + ' "$FILE" > "$FILE.tmp" && mv -f "$FILE.tmp" "$FILE" + + echo "[+] Updated WP_HOME and WP_SITEURL in $FILE" + done +} + + + + + + + + nginx_br() { local mode=$1 @@ -1990,19 +2121,11 @@ nginx_gzip() { web_security() { send_stats "LDNMP環境防禦" while true; do + check_f2b_status check_waf_status check_cf_mode - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "服務器網站防禦程序${check_docker}${gl_lv}${CFmessage}${waf_status}${gl_bai}" + echo -e "服務器網站防禦程序${check_f2b_status}${gl_lv}${CFmessage}${waf_status}${gl_bai}" echo "------------------------" echo "1. 安裝防禦程序" echo "------------------------" @@ -2024,11 +2147,16 @@ web_security() { case $sub_choice in 1) f2b_install_sshd - cd /path/to/fail2ban/config/fail2ban/filter.d + cd /etc/fail2ban/filter.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/fail2ban-nginx-cc.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-418.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-deny.conf + wget ${gh_proxy}raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-unauthorized.conf + wget ${gh_proxy}https://raw.githubusercontent.com/linuxserver/fail2ban-confs/master/filter.d/nginx-bad-request.conf + + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - sed -i "/cloudflare/d" /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + sed -i "/cloudflare/d" /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status ;; 5) @@ -2042,56 +2170,57 @@ web_security() { local xxx="fail2ban-nginx-cc" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-418" + local xxx="nginx-418" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-bad-request" + local xxx="nginx-bad-request" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-badbots" + local xxx="nginx-badbots" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-botsearch" + local xxx="nginx-botsearch" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-deny" + local xxx="nginx-deny" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-http-auth" + local xxx="nginx-http-auth" f2b_status_xxx echo "------------------------" - local xxx="docker-nginx-unauthorized" + local xxx="nginx-unauthorized" f2b_status_xxx echo "------------------------" - local xxx="docker-php-url-fopen" + local xxx="php-url-fopen" f2b_status_xxx echo "------------------------" ;; 7) - docker exec -it fail2ban fail2ban-client status + fail2ban-client status ;; 8) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log + tail -f /var/log/fail2ban.log ;; 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban + remove fail2ban + rm -rf /etc/fail2ban crontab -l | grep -v "CF-Under-Attack.sh" | crontab - 2>/dev/null echo "Fail2Ban防禦程序已卸載" + break ;; 11) install nano - nano /path/to/fail2ban/config/fail2ban/jail.d/nginx-docker-cc.conf + nano /etc/fail2ban/jail.d/nginx-docker-cc.conf f2b_status break ;; 12) - docker exec -it fail2ban fail2ban-client unban --all + fail2ban-client unban --all ;; 21) @@ -2104,14 +2233,14 @@ web_security() { wget -O /home/web/conf.d/default.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/default11.conf docker exec nginx nginx -s reload - cd /path/to/fail2ban/config/fail2ban/jail.d/ + cd /etc/fail2ban/jail.d/ curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/nginx-docker-cc.conf - cd /path/to/fail2ban/config/fail2ban/action.d + cd /etc/fail2ban/action.d curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/cloudflare-docker.conf - sed -i "s/kejilion@outlook.com/$cfuser/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf - sed -i "s/APIKEY00000/$cftoken/g" /path/to/fail2ban/config/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/kejilion@outlook.com/$cfuser/g" /etc/fail2ban/action.d/cloudflare-docker.conf + sed -i "s/APIKEY00000/$cftoken/g" /etc/fail2ban/action.d/cloudflare-docker.conf f2b_status echo "已配置cloudflare模式,可在cf後台,站點-安全性-事件中查看攔截記錄" @@ -2176,26 +2305,23 @@ web_security() { break ;; esac - fi break_end done } -check_nginx_mode() { - -CONFIG_FILE="/home/web/nginx.conf" +check_ldnmp_mode() { -# 獲取當前的 worker_processes 設置值 -current_value=$(grep -E '^\s*worker_processes\s+[0-9]+;' "$CONFIG_FILE" | awk '{print $2}' | tr -d ';') + local MYSQL_CONTAINER="mysql" + local MYSQL_CONF="/etc/mysql/conf.d/custom_mysql_config.cnf" -# 根據值設置模式信息 -if [ "$current_value" = "8" ]; then - mode_info=" 高性能模式" -else - mode_info=" 标准模式" -fi + # 檢查 MySQL 配置文件中是否包含 4096M + if docker exec "$MYSQL_CONTAINER" grep -q "4096M" "$MYSQL_CONF" 2>/dev/null; then + mode_info="高性能模式" + else + mode_info="標準模式" + fi @@ -2204,25 +2330,25 @@ fi check_nginx_compression() { - CONFIG_FILE="/home/web/nginx.conf" + local CONFIG_FILE="/home/web/nginx.conf" # 檢查 zstd 是否開啟且未被註釋(整行以 zstd on; 開頭) if grep -qE '^\s*zstd\s+on;' "$CONFIG_FILE"; then - zstd_status=" zstd压缩已开启" + zstd_status="zstd壓縮已開啟" else zstd_status="" fi # 檢查 brotli 是否開啟且未被註釋 if grep -qE '^\s*brotli\s+on;' "$CONFIG_FILE"; then - br_status=" br压缩已开启" + br_status="br壓縮已開啟" else br_status="" fi # 檢查 gzip 是否開啟且未被註釋 if grep -qE '^\s*gzip\s+on;' "$CONFIG_FILE"; then - gzip_status=" gzip压缩已开启" + gzip_status="gzip壓縮已開啟" else gzip_status="" fi @@ -2233,7 +2359,7 @@ check_nginx_compression() { web_optimization() { while true; do - check_nginx_mode + check_ldnmp_mode check_nginx_compression clear send_stats "優化LDNMP環境" @@ -2252,9 +2378,11 @@ web_optimization() { 1) send_stats "站點標準模式" - # nginx調優 - sed -i 's/worker_connections.*/worker_connections 10240;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 4;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((1024 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf + # php調優 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2282,7 +2410,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_balanced @@ -2293,8 +2420,10 @@ web_optimization() { send_stats "站點高性能模式" # nginx調優 - sed -i 's/worker_connections.*/worker_connections 20480;/' /home/web/nginx.conf - sed -i 's/worker_processes.*/worker_processes 8;/' /home/web/nginx.conf + local cpu_cores=$(nproc) + local connections=$((2048 * ${cpu_cores})) + sed -i "s/worker_processes.*/worker_processes ${cpu_cores};/" /home/web/nginx.conf + sed -i "s/worker_connections.*/worker_connections ${connections};/" /home/web/nginx.conf # php調優 wget -O /home/optimized_php.ini ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/optimized_php.ini @@ -2321,7 +2450,6 @@ web_optimization() { cd /home/web && docker compose restart - restart_redis optimize_web_server echo "LDNMP環境已設置成 高性能模式" @@ -2371,18 +2499,25 @@ web_optimization() { +check_docker_app() { + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name" ; then + check_docker="${gl_lv}已安裝${gl_bai}" + else + check_docker="${gl_hui}未安裝${gl_bai}" + fi +} -check_docker_app() { +# check_docker_app() { -if docker inspect "$docker_name" &>/dev/null; then - check_docker="${gl_lv}已安装${gl_bai}" -else - check_docker="${gl_hui}未安装${gl_bai}" -fi +# if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then +# check_docker="${gl_lv}已安裝${gl_bai}" +# else +# check_docker="${gl_hui}未安裝${gl_bai}" +# fi -} +# } check_docker_app_ip() { @@ -2416,54 +2551,61 @@ done check_docker_image_update() { - local container_name=$1 + update_status="" - local country=$(curl -s ipinfo.io/country) - if [[ "$country" == "CN" ]]; then - update_status="" - return - fi + # 1. 區域檢查 + local country=$(curl -s --max-time 2 ipinfo.io/country) + [[ "$country" == "CN" ]] && return - # 獲取容器的創建時間和鏡像名稱 + # 2. 獲取本地鏡像信息 local container_info=$(docker inspect --format='{{.Created}},{{.Config.Image}}' "$container_name" 2>/dev/null) - local container_created=$(echo "$container_info" | cut -d',' -f1) - local image_name=$(echo "$container_info" | cut -d',' -f2) - - # 提取鏡像倉庫和標籤 - local image_repo=${image_name%%:*} - local image_tag=${image_name##*:} + [[ -z "$container_info" ]] && return - # 默認標籤為 latest - [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" - - # 添加對官方鏡像的支持 - [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" + local container_created=$(echo "$container_info" | cut -d',' -f1) + local full_image_name=$(echo "$container_info" | cut -d',' -f2) + local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) + + # 3. 智能路由判斷 + if [[ "$full_image_name" == ghcr.io* ]]; then + # --- 場景 A: 鏡像在 GitHub (ghcr.io) --- + # 提取倉庫路徑,例如 ghcr.io/onexru/oneimg -> onexru/oneimg + local repo_path=$(echo "$full_image_name" | sed 's/ghcr.io\///' | cut -d':' -f1) + # 注意:ghcr.io 的 API 比較複雜,通常最快的方法是查 GitHub Repo 的 Release + local api_url="https://api.github.com/repos/$repo_path/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) + + elif [[ "$full_image_name" == *"oneimg"* ]]; then + # --- 場景 B: 特殊指定 (即便在 Docker Hub,也想通過 GitHub Release 判斷) --- + local api_url="https://api.github.com/repos/onexru/oneimg/releases/latest" + local remote_date=$(curl -s "$api_url" | jq -r '.published_at' 2>/dev/null) - # 從 Docker Hub API 獲取鏡像發佈時間 - local hub_info=$(curl -s "https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag") - local last_updated=$(echo "$hub_info" | jq -r '.last_updated' 2>/dev/null) + else + # --- 場景 C: 標準 Docker Hub --- + local image_repo=${full_image_name%%:*} + local image_tag=${full_image_name##*:} + [[ "$image_repo" == "$image_tag" ]] && image_tag="latest" + [[ "$image_repo" != */* ]] && image_repo="library/$image_repo" - # 驗證獲取的時間 - if [[ -n "$last_updated" && "$last_updated" != "null" ]]; then - local container_created_ts=$(date -d "$container_created" +%s 2>/dev/null) - local last_updated_ts=$(date -d "$last_updated" +%s 2>/dev/null) + local api_url="https://hub.docker.com/v2/repositories/$image_repo/tags/$image_tag" + local remote_date=$(curl -s "$api_url" | jq -r '.last_updated' 2>/dev/null) + fi - # 比較時間戳 - if [[ $container_created_ts -lt $last_updated_ts ]]; then - update_status="${gl_huang}发现新版本!${gl_bai}" - else - update_status="" + # 4. 時間戳對比 + if [[ -n "$remote_date" && "$remote_date" != "null" ]]; then + local remote_ts=$(date -d "$remote_date" +%s 2>/dev/null) + if [[ $container_created_ts -lt $remote_ts ]]; then + update_status="${gl_huang}發現新版本!${gl_bai}" fi - else - update_status="" fi - } + + + block_container_port() { local container_name_or_id=$1 local allowed_ip=$2 @@ -2698,16 +2840,33 @@ clear_host_port_rules() { setup_docker_dir() { - mkdir -p /home/docker/ 2>/dev/null + mkdir -p /home /home/docker 2>/dev/null + if [ -d "/vol1/1000/" ] && [ ! -d "/vol1/1000/docker" ]; then cp -f /home/docker /home/docker1 2>/dev/null rm -rf /home/docker 2>/dev/null mkdir -p /vol1/1000/docker 2>/dev/null ln -s /vol1/1000/docker /home/docker 2>/dev/null fi + + if [ -d "/volume1/" ] && [ ! -d "/volume1/docker" ]; then + cp -f /home/docker /home/docker1 2>/dev/null + rm -rf /home/docker 2>/dev/null + mkdir -p /volume1/docker 2>/dev/null + ln -s /volume1/docker /home/docker 2>/dev/null + fi + + } +add_app_id() { +mkdir -p /home/docker +touch /home/docker/appno.txt +grep -qxF "${app_id}" /home/docker/appno.txt || echo "${app_id}" >> /home/docker/appno.txt + +} + docker_app() { @@ -2720,7 +2879,7 @@ while true; do echo -e "$docker_name $check_docker $update_status" echo "$docker_describe" echo "$docker_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2741,7 +2900,8 @@ while true; do read -e -p "請輸入你的選擇:" choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "輸入應用對外服務端口,回車默認使用${docker_port}端口:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port @@ -2749,9 +2909,10 @@ while true; do install jq install_docker docker_rum - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + add_app_id + clear echo "$docker_name已經安裝完成" check_docker_app_ip @@ -2764,6 +2925,9 @@ while true; do docker rm -f "$docker_name" docker rmi -f "$docker_img" docker_rum + + add_app_id + clear echo "$docker_name已經安裝完成" check_docker_app_ip @@ -2777,6 +2941,8 @@ while true; do docker rmi -f "$docker_img" rm -rf "/home/docker/$docker_name" rm -f /home/docker/${docker_name}_port.conf + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "應用已卸載" send_stats "解除安裝$docker_name" ;; @@ -2817,7 +2983,6 @@ done - docker_app_plus() { send_stats "$app_name" while true; do @@ -2827,7 +2992,7 @@ docker_app_plus() { echo -e "$app_name $check_docker $update_status" echo "$app_text" echo "$app_url" - if docker inspect "$docker_name" &>/dev/null; then + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then if [ ! -f "/home/docker/${docker_name}_port.conf" ]; then local docker_port=$(docker port "$docker_name" | head -n1 | awk -F'[:]' '/->/ {print $NF; exit}') docker_port=${docker_port:-0000} @@ -2848,29 +3013,41 @@ docker_app_plus() { read -e -p "輸入你的選擇:" choice case $choice in 1) - check_disk_space $app_size + setup_docker_dir + check_disk_space $app_size /home/docker read -e -p "輸入應用對外服務端口,回車默認使用${docker_port}端口:" app_port local app_port=${app_port:-${docker_port}} local docker_port=$app_port install jq install_docker docker_app_install - setup_docker_dir echo "$docker_port" > "/home/docker/${docker_name}_port.conf" + + add_app_id + send_stats "$app_name安裝" ;; + 2) docker_app_update + add_app_id + send_stats "$app_name更新" ;; + 3) docker_app_uninstall rm -f /home/docker/${docker_name}_port.conf + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "$app_name解除安裝" ;; + 5) echo "${docker_name}域名訪問設置" send_stats "${docker_name}域名訪問設置" add_yuming ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} block_container_port "$docker_name" "$ipv4_address" + ;; 6) echo "域名格式 example.com 不帶https://" @@ -2920,7 +3097,7 @@ docker network create $NETWORK_NAME docker run -d \ --name=node-exporter \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ prom/node-exporter # Run Prometheus container @@ -2929,7 +3106,7 @@ docker run -d \ -v $PROMETHEUS_DIR/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $PROMETHEUS_DIR/data:/prometheus \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ --user 0:0 \ prom/prometheus:latest @@ -2939,7 +3116,7 @@ docker run -d \ -p ${docker_port}:3000 \ -v $GRAFANA_DIR:/var/lib/grafana \ --network $NETWORK_NAME \ - --restart unless-stopped \ + --restart=always \ grafana/grafana:latest } @@ -2985,55 +3162,44 @@ tmux new -d -s "$base_name-$tmuxd_ID" "$tmuxd" f2b_status() { - docker exec -it fail2ban fail2ban-client reload + fail2ban-client reload sleep 3 - docker exec -it fail2ban fail2ban-client status + fail2ban-client status } f2b_status_xxx() { - docker exec -it fail2ban fail2ban-client status $xxx + fail2ban-client status $xxx } -f2b_install_sshd() { - - docker run -d \ - --name=fail2ban \ - --net=host \ - --cap-add=NET_ADMIN \ - --cap-add=NET_RAW \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e VERBOSITY=-vv \ - -v /path/to/fail2ban/config:/config \ - -v /var/log:/var/log:ro \ - -v /home/web/log/nginx/:/remotelogs/nginx:ro \ - --restart unless-stopped \ - lscr.io/linuxserver/fail2ban:latest - - sleep 3 - if grep -q 'Alpine' /etc/issue; then - cd /path/to/fail2ban/config/fail2ban/filter.d - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd.conf - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-sshd-ddos.conf - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/alpine-ssh.conf - elif command -v dnf &>/dev/null; then - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf +check_f2b_status() { + if command -v fail2ban-client >/dev/null 2>&1; then + check_f2b_status="${gl_lv}已安裝${gl_bai}" else - install rsyslog - systemctl start rsyslog - systemctl enable rsyslog - cd /path/to/fail2ban/config/fail2ban/jail.d/ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/linux-ssh.conf - systemctl restart rsyslog + check_f2b_status="${gl_hui}未安裝${gl_bai}" fi - - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf } -f2b_sshd() { +f2b_install_sshd() { + + docker rm -f fail2ban >/dev/null 2>&1 + install fail2ban + start fail2ban + enable fail2ban + + if command -v dnf &>/dev/null; then + cd /etc/fail2ban/jail.d/ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/config/main/fail2ban/centos-ssh.conf + fi + + if command -v apt &>/dev/null; then + install rsyslog + systemctl start rsyslog + systemctl enable rsyslog + fi + +} + +f2b_sshd() { if grep -q 'Alpine' /etc/issue; then xxx=alpine-sshd f2b_status_xxx @@ -3113,8 +3279,7 @@ send_stats "安裝LDNMP環境" root_use clear echo -e "${gl_huang}LDNMP環境未安裝,開始安裝LDNMP環境...${gl_bai}" -check_disk_space 3 -check_port +check_disk_space 3 /home install_dependency install_docker install_certbot @@ -3130,8 +3295,7 @@ send_stats "安裝nginx環境" root_use clear echo -e "${gl_huang}nginx未安裝,開始安裝nginx環境...${gl_bai}" -check_disk_space 1 -check_port +check_disk_space 1 /home install_dependency install_docker install_certbot @@ -3181,10 +3345,21 @@ ldnmp_web_on() { } nginx_web_on() { - clear - echo "您的$webname搭建好了!" - echo "https://$yuming" + clear + + local ipv4_pattern='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' + local ipv6_pattern='^(([0-9A-Fa-f]{1,4}:){1,7}:|([0-9A-Fa-f]{1,4}:){7,7}[0-9A-Fa-f]{1,4}|::1)$' + echo "您的$webname搭建好了!" + + if [[ "$yuming" =~ $ipv4_pattern || "$yuming" =~ $ipv6_pattern ]]; then + mv /home/web/conf.d/"$yuming".conf /home/web/conf.d/"${yuming}_${access_port}".conf + echo "http://$yuming:$access_port" + elif grep -q '^[[:space:]]*#.*if (\$scheme = http)' "/home/web/conf.d/"$yuming".conf"; then + echo "http://$yuming" + else + echo "https://$yuming" + fi } @@ -3201,40 +3376,38 @@ ldnmp_wp() { fi repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/wordpress.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf nginx_http_on + install_ssltls + certs_status + add_db + cd /home/web/html mkdir $yuming cd $yuming wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/refs/heads/main/wp-latest.zip - # wget -O latest.zip https://cn.wordpress.org/latest-zh_CN.zip - # wget -O latest.zip https://wordpress.org/latest.zip unzip latest.zip rm latest.zip - echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php + echo "define('FS_METHOD', 'direct'); define('WP_REDIS_HOST', 'redis'); define('WP_REDIS_PORT', '6379'); define('WP_REDIS_MAXTTL', 86400); define('WP_CACHE_KEY_SALT', '${yuming}_');" >> /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|database_name_here|$dbname|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|username_here|$dbuse|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|password_here|$dbusepasswd|g" /home/web/html/$yuming/wordpress/wp-config-sample.php sed -i "s|localhost|mysql|g" /home/web/html/$yuming/wordpress/wp-config-sample.php + patch_wp_url "https://$yuming" "https://$yuming" cp /home/web/html/$yuming/wordpress/wp-config-sample.php /home/web/html/$yuming/wordpress/wp-config.php + restart_ldnmp nginx_web_on -# echo "數據庫名: $dbname" -# echo "用戶名: $dbuse" -# echo "密碼: $dbusepasswd" -# echo "數據庫地址: mysql" -# echo "表前綴: wp_" } + ldnmp_Proxy() { clear webname="反向代理-IP+端口" @@ -3247,21 +3420,43 @@ ldnmp_Proxy() { if [ -z "$yuming" ]; then add_yuming fi + + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy" ]; then - read -e -p "請輸入你的反代IP:" reverseproxy + read -e -p "請輸入你的反代IP (回車默認本機IP 127.0.0.1):" reverseproxy + reverseproxy=${reverseproxy:-127.0.0.1} fi if [ -z "$port" ]; then read -e -p "請輸入你的反代端口:" port fi nginx_install_status + + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + install_ssltls certs_status - wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf - wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy.conf + + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf + + sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - sed -i "s/0.0.0.0/$reverseproxy/g" /home/web/conf.d/$yuming.conf - sed -i "s|0000|$port|g" /home/web/conf.d/$yuming.conf + + reverseproxy_port="$reverseproxy:$port" + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 動態添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i '/remote_addr/d' /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" + nginx_http_on docker exec nginx nginx -s reload nginx_web_on @@ -3271,9 +3466,7 @@ ldnmp_Proxy() { ldnmp_Proxy_backend() { clear - webname="反向代理-负载均衡" - yuming="${1:-}" - reverseproxy_port="${2:-}" + webname="反向代理-負載均衡" send_stats "安裝$webname" echo "開始部署$webname" @@ -3281,31 +3474,35 @@ ldnmp_Proxy_backend() { add_yuming fi - # 獲取用戶輸入的多個IP:端口(用空格分隔) + check_ip_and_get_access_port "$yuming" + if [ -z "$reverseproxy_port" ]; then read -e -p "請輸入你的多個反代IP+端口用空格隔開(例如 127.0.0.1:3000 127.0.0.1:3002):" reverseproxy_port fi nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend.conf + + install_ssltls + certs_status + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) sed -i "s/backend_yuming_com/backend_$backend/g" /home/web/conf.d/"$yuming".conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf - # 動態生成 upstream 配置 upstream_servers="" for server in $reverseproxy_port; do upstream_servers="$upstream_servers server $server;\n" done - # 替換模板中的佔位符 - sed -i "s/# 动态添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + sed -i "s/# 動態添加/$upstream_servers/g" /home/web/conf.d/$yuming.conf + + update_nginx_listen_port "$yuming" "$access_port" nginx_http_on docker exec nginx nginx -s reload @@ -3314,6 +3511,200 @@ ldnmp_Proxy_backend() { + + + +list_stream_services() { + + STREAM_DIR="/home/web/stream.d" + printf "%-25s %-18s %-25s %-20s\n" "服務名" "通信類型" "本機地址" "後端地址" + + if [ -z "$(ls -A "$STREAM_DIR")" ]; then + return + fi + + for conf in "$STREAM_DIR"/*; do + # 服務名取文件名 + service_name=$(basename "$conf" .conf) + + # 獲取 upstream 塊中的 server 後端 IP:端口 + backend=$(grep -Po '(?<=server )[^;]+' "$conf" | head -n1) + + # 獲取 listen 端口 + listen_port=$(grep -Po '(?<=listen )[^;]+' "$conf" | head -n1) + + # 默認本地 IP + ip_address + local_ip="$ipv4_address" + + # 獲取通信類型,優先從文件名後綴或內容判斷 + if grep -qi 'udp;' "$conf"; then + proto="udp" + else + proto="tcp" + fi + + # 拼接監聽 IP:端口 + local_addr="$local_ip:$listen_port" + + printf "%-22s %-14s %-21s %-20s\n" "$service_name" "$proto" "$local_addr" "$backend" + done +} + + + + + + + + + +stream_panel() { + send_stats "Stream四層代理" + local app_id="104" + local docker_name="nginx" + + while true; do + clear + check_docker_app + check_docker_image_update $docker_name + echo -e "Stream四層代理轉發工具$check_docker $update_status" + echo "NGINX Stream 是 NGINX 的 TCP/UDP 代理模塊,用於實現高性能的 傳輸層流量轉發和負載均衡。" + echo "------------------------" + if [ -d "/home/web/stream.d" ]; then + list_stream_services + fi + echo "" + echo "------------------------" + echo "1. 安裝 2. 更新 3. 卸載" + echo "------------------------" + echo "4. 添加轉發服務 5. 修改轉發服務 6. 刪除轉發服務" + echo "------------------------" + echo "0. 返回上一級選單" + echo "------------------------" + read -e -p "輸入你的選擇:" choice + case $choice in + 1) + nginx_install_status + add_app_id + send_stats "安裝Stream四層代理" + ;; + 2) + update_docker_compose_with_db_creds + nginx_upgrade + add_app_id + send_stats "更新Stream四層代理" + ;; + 3) + read -e -p "確定要刪除 nginx 容器嗎?這可能會影響網站功能! (y/N):" confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + docker rm -f nginx + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + send_stats "更新Stream四層代理" + echo "nginx 容器已刪除。" + else + echo "操作已取消。" + fi + + ;; + + 4) + ldnmp_Proxy_backend_stream + add_app_id + send_stats "添加四層代理" + ;; + 5) + send_stats "編輯轉發配置" + read -e -p "請輸入你要編輯的服務名:" stream_name + install nano + nano /home/web/stream.d/$stream_name.conf + docker restart nginx + send_stats "修改四層代理" + ;; + 6) + send_stats "刪除轉發配置" + read -e -p "請輸入你要刪除的服務名:" stream_name + rm /home/web/stream.d/$stream_name.conf > /dev/null 2>&1 + docker restart nginx + send_stats "刪除四層代理" + ;; + *) + break + ;; + esac + break_end + done +} + + + +ldnmp_Proxy_backend_stream() { + clear + webname="Stream四層代理-負載均衡" + + send_stats "安裝$webname" + echo "開始部署$webname" + + # 獲取代理名稱 + read -rp "請輸入代理轉發名稱 (如 mysql_proxy):" proxy_name + if [ -z "$proxy_name" ]; then + echo "名稱不能為空"; return 1 + fi + + # 獲取監聽端口 + read -rp "請輸入本機監聽端口 (如 3306):" listen_port + if ! [[ "$listen_port" =~ ^[0-9]+$ ]]; then + echo "端口必須是數字"; return 1 + fi + + echo "請選擇協議類型:" + echo "1. TCP 2. UDP" + read -rp "請輸入序號 [1-2]:" proto_choice + + case "$proto_choice" in + 1) proto="tcp"; listen_suffix="" ;; + 2) proto="udp"; listen_suffix=" udp" ;; + *) echo "無效選擇"; return 1 ;; + esac + + read -e -p "請輸入你的一個或者多個後端IP+端口用空格隔開(例如 10.13.0.2:3306 10.13.0.3:3306):" reverseproxy_port + + nginx_install_status + cd /home && mkdir -p web/stream.d + grep -q '^[[:space:]]*stream[[:space:]]*{' /home/web/nginx.conf || echo -e '\nstream {\n include /etc/nginx/stream.d/*.conf;\n}' | tee -a /home/web/nginx.conf + wget -O /home/web/stream.d/$proxy_name.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-backend-stream.conf + + backend=$(tr -dc 'A-Za-z' < /dev/urandom | head -c 8) + sed -i "s/backend_yuming_com/${proxy_name}_${backend}/g" /home/web/stream.d/"$proxy_name".conf + sed -i "s|listen 80|listen $listen_port $listen_suffix|g" /home/web/stream.d/$proxy_name.conf + sed -i "s|listen \[::\]:|listen [::]:${listen_port} ${listen_suffix}|g" "/home/web/stream.d/${proxy_name}.conf" + + upstream_servers="" + for server in $reverseproxy_port; do + upstream_servers="$upstream_servers server $server;\n" + done + + sed -i "s/# 動態添加/$upstream_servers/g" /home/web/stream.d/$proxy_name.conf + + docker exec nginx nginx -s reload + clear + echo "您的$webname搭建好了!" + echo "------------------------" + echo "訪問地址:" + ip_address + if [ -n "$ipv4_address" ]; then + echo "$ipv4_address:${listen_port}" + fi + if [ -n "$ipv6_address" ]; then + echo "$ipv6_address:${listen_port}" + fi + echo "" +} + + + + + find_container_by_host_port() { port="$1" docker_name=$(docker ps --format '{{.ID}} {{.Names}}' | while read id name; do @@ -3331,11 +3722,11 @@ ldnmp_web_status() { root_use while true; do local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) - local output="站点: ${gl_lv}${cert_count}${gl_bai}" + local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) - local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" + local db_output="${gl_lv}${db_count}${gl_bai}" clear send_stats "LDNMP站點管理" @@ -3343,8 +3734,7 @@ ldnmp_web_status() { echo "------------------------" ldnmp_v - # ls -t /home/web/conf.d | sed 's/\.[^.]*$//' - echo -e "${output}證書到期時間" + echo -e "站點:${output}證書到期時間" echo -e "------------------------" for cert_file in /home/web/certs/*_cert.pem; do local domain=$(basename "$cert_file" | sed 's/_cert.pem//') @@ -3355,9 +3745,28 @@ ldnmp_web_status() { fi done + for conf_file in /home/web/conf.d/*_*.conf; do + [ -e "$conf_file" ] || continue + basename "$conf_file" .conf + done + + for conf_file in /home/web/conf.d/*.conf; do + [ -e "$conf_file" ] || continue + + filename=$(basename "$conf_file") + + if [ "$filename" = "map.conf" ] || [ "$filename" = "default.conf" ]; then + continue + fi + + if ! grep -q "ssl_certificate" "$conf_file"; then + basename "$conf_file" .conf + fi + done + echo "------------------------" echo "" - echo -e "${db_output}" + echo -e "資料庫:${db_output}" echo -e "------------------------" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml | tr -d '[:space:]') docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2> /dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" @@ -3371,11 +3780,11 @@ ldnmp_web_status() { echo "" echo "操作" echo "------------------------" - echo "1. 申請/更新域名證書 2. 更換站點域名" + echo "1. 申請/更新域名證書 2. 克隆站點域名" echo "3. 清理站點緩存 4. 創建關聯站點" echo "5. 查看訪問日誌 6. 查看錯誤日誌" echo "7. 編輯全局配置 8. 編輯站點配置" - echo "9. 管理站點數據庫 10. 查看站點分析報告" + echo "9. 管理站點數據庫 10. 查看站點分析報告" echo "------------------------" echo "20. 刪除指定站點數據" echo "------------------------" @@ -3387,30 +3796,26 @@ ldnmp_web_status() { send_stats "申請域名證書" read -e -p "請輸入你的域名:" yuming install_certbot - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null install_ssltls certs_status ;; 2) - send_stats "更換站點域名" - echo -e "${gl_hong}強烈建議:${gl_bai}先備份好全站數據再更換站點域名!" + send_stats "克隆站點域名" read -e -p "請輸入舊域名:" oddyuming read -e -p "請輸入新域名:" yuming install_certbot install_ssltls certs_status - # mysql替換 - add_db + add_db local odd_dbname=$(echo "$oddyuming" | sed -e 's/[^A-Za-z0-9]/_/g') local odd_dbname="${odd_dbname}" docker exec mysql mysqldump -u root -p"$dbrootpasswd" $odd_dbname | docker exec -i mysql mysql -u root -p"$dbrootpasswd" $dbname - docker exec mysql mysql -u root -p"$dbrootpasswd" -e "DROP DATABASE $odd_dbname;" - local tables=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -D $dbname -e "SHOW TABLES;" | awk '{ if (NR>1) print $1 }') for table in $tables; do @@ -3421,18 +3826,15 @@ ldnmp_web_status() { done # 網站目錄替換 - mv /home/web/html/$oddyuming /home/web/html/$yuming + cp -r /home/web/html/$oddyuming /home/web/html/$yuming find /home/web/html/$yuming -type f -exec sed -i "s/$odd_dbname/$dbname/g" {} + find /home/web/html/$yuming -type f -exec sed -i "s/$oddyuming/$yuming/g" {} + - mv /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf + cp /home/web/conf.d/$oddyuming.conf /home/web/conf.d/$yuming.conf sed -i "s/$oddyuming/$yuming/g" /home/web/conf.d/$yuming.conf - rm /home/web/certs/${oddyuming}_key.pem - rm /home/web/certs/${oddyuming}_cert.pem - - docker exec nginx nginx -s reload + cd /home/web && docker compose restart ;; @@ -3493,7 +3895,7 @@ ldnmp_web_status() { 20) web_del - docker run -it --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null + docker run --rm -v /etc/letsencrypt/:/etc/letsencrypt certbot/certbot delete --cert-name "$yuming" -n 2>/dev/null ;; *) @@ -3508,7 +3910,7 @@ ldnmp_web_status() { check_panel_app() { if $lujing > /dev/null 2>&1; then - check_panel="${gl_lv}已安装${gl_bai}" + check_panel="${gl_lv}已安裝${gl_bai}" else check_panel="" fi @@ -3538,15 +3940,21 @@ while true; do install wget iptables_open panel_app_install + + add_app_id send_stats "${panelname}安裝" ;; 2) panel_app_manage + + add_app_id send_stats "${panelname}控制" ;; 3) panel_app_uninstall + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt send_stats "${panelname}解除安裝" ;; *) @@ -3563,9 +3971,9 @@ done check_frp_app() { if [ -d "/home/frp/" ]; then - check_frp="${gl_lv}已安装${gl_bai}" + check_frp="${gl_lv}已安裝${gl_bai}" else - check_frp="${gl_hui}未安装${gl_bai}" + check_frp="${gl_hui}未安裝${gl_bai}" fi } @@ -3658,7 +4066,7 @@ add_forwarding_service() { send_stats "添加frp內網服務" # 提示用戶輸入服務名稱和轉發信息 read -e -p "請輸入服務名稱:" service_name - read -e -p "請輸入轉發類型 (tcp/udp) [回車默認tcp]:" service_type + read -e -p "請輸入轉發類型 (tcp/udp) [回​​車默認tcp]:" service_type local service_type=${service_type:-tcp} read -e -p "請輸入內網IP [回車默認127.0.0.1]:" local_ip local local_ip=${local_ip:-127.0.0.1} @@ -3703,7 +4111,7 @@ list_forwarding_services() { local config_file="$1" # 打印表頭 - printf "%-20s %-25s %-30s %-10s\n" "服务名称" "内网地址" "外网地址" "协议" + printf "%-20s %-25s %-30s %-10s\n" "服務名稱" "內網地址" "外網地址" "協定" awk ' BEGIN { @@ -3845,6 +4253,7 @@ frps_main_ports() { frps_panel() { send_stats "FRP服務端" + local app_id="55" local docker_name="frps" local docker_port=8056 while true; do @@ -3875,6 +4284,8 @@ frps_panel() { install jq grep ss install_docker generate_frps_config + + add_app_id echo "FRP服務端已經安裝完成" ;; 2) @@ -3883,6 +4294,8 @@ frps_panel() { docker rm -f frps && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frps.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frps.toml /home/frp/frps.toml donlond_frp frps + + add_app_id echo "FRP服務端已經更新完成" ;; 3) @@ -3893,6 +4306,7 @@ frps_panel() { close_port 8055 8056 + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "應用已卸載" ;; 5) @@ -3937,6 +4351,7 @@ frps_panel() { frpc_panel() { send_stats "FRP客戶端" + local app_id="56" local docker_name="frpc" local docker_port=8055 while true; do @@ -3966,6 +4381,8 @@ frpc_panel() { install jq grep ss install_docker configure_frpc + + add_app_id echo "FRP客戶端已經安裝完成" ;; 2) @@ -3974,6 +4391,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine >/dev/null 2>&1 [ -f /home/frp/frpc.toml ] || cp /home/frp/frp_0.61.0_linux_amd64/frpc.toml /home/frp/frpc.toml donlond_frp frpc + + add_app_id echo "FRP客戶端已經更新完成" ;; @@ -3983,6 +4402,8 @@ frpc_panel() { docker rm -f frpc && docker rmi kjlion/frp:alpine rm -rf /home/frp close_port 8055 + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "應用已卸載" ;; @@ -4013,6 +4434,7 @@ frpc_panel() { yt_menu_pro() { + local app_id="66" local VIDEO_DIR="/home/yt-dlp" local URL_FILE="$VIDEO_DIR/urls.txt" local ARCHIVE_FILE="$VIDEO_DIR/archive.txt" @@ -4022,9 +4444,9 @@ yt_menu_pro() { while true; do if [ -x "/usr/local/bin/yt-dlp" ]; then - local YTDLP_STATUS="${gl_lv}已安装${gl_bai}" + local YTDLP_STATUS="${gl_lv}已安裝${gl_bai}" else - local YTDLP_STATUS="${gl_hui}未安装${gl_bai}" + local YTDLP_STATUS="${gl_hui}未安裝${gl_bai}" fi clear @@ -4050,20 +4472,26 @@ yt_menu_pro() { send_stats "正在安裝 yt-dlp..." echo "正在安裝 yt-dlp..." install ffmpeg - sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp - sudo chmod a+rx /usr/local/bin/yt-dlp + curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp + chmod a+rx /usr/local/bin/yt-dlp + + add_app_id echo "安裝完成。按任意鍵繼續..." read ;; 2) send_stats "正在更新 yt-dlp..." echo "正在更新 yt-dlp..." - sudo yt-dlp -U + yt-dlp -U + + add_app_id echo "更新完成。按任意鍵繼續..." read ;; 3) send_stats "正在卸載 yt-dlp..." echo "正在卸載 yt-dlp..." - sudo rm -f /usr/local/bin/yt-dlp + rm -f /usr/local/bin/yt-dlp + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt echo "卸載完成。按任意鍵繼續..." read ;; 5) @@ -4266,9 +4694,8 @@ linux_clean() { bbr_on() { -cat > /etc/sysctl.conf << EOF -net.ipv4.tcp_congestion_control=bbr -EOF +sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf +echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p } @@ -4278,8 +4705,8 @@ set_dns() { ip_address -rm /etc/resolv.conf -touch /etc/resolv.conf +chattr -i /etc/resolv.conf +> /etc/resolv.conf if [ -n "$ipv4_address" ]; then echo "nameserver $dns1_ipv4" >> /etc/resolv.conf @@ -4291,6 +4718,13 @@ if [ -n "$ipv6_address" ]; then echo "nameserver $dns2_ipv6" >> /etc/resolv.conf fi +if [ ! -s /etc/resolv.conf ]; then + echo "nameserver 223.5.5.5" >> /etc/resolv.conf + echo "nameserver 8.8.8.8" >> /etc/resolv.conf +fi + +chattr +i /etc/resolv.conf + } @@ -4335,7 +4769,9 @@ while true; do ;; 3) install nano + chattr -i /etc/resolv.conf nano /etc/resolv.conf + chattr +i /etc/resolv.conf send_stats "手動編輯DNS配置" ;; *) @@ -4495,6 +4931,7 @@ dd_xitong() { dd_xitong_1() { echo -e "重裝後初始用戶名:${gl_huang}root${gl_bai}初始密碼:${gl_huang}LeitboGi0ro${gl_bai}初始端口:${gl_huang}22${gl_bai}" + echo -e "${gl_huang}重裝後請及時修改初始密碼,防止暴力入侵。命令行輸入passwd修改密碼${gl_bai}" echo -e "按任意鍵繼續..." read -n 1 -s -r -p "" install wget @@ -4528,10 +4965,12 @@ dd_xitong() { echo "重裝系統" echo "--------------------------------" echo -e "${gl_hong}注意:${gl_bai}重裝有風險失聯,不放心者慎用。重裝預計花費15分鐘,請提前備份數據。" - echo -e "${gl_hui}感謝MollyLau大佬和bin456789大佬的腳本支持!${gl_bai} " + echo -e "${gl_hui}感謝bin456789大佬和leitbogioro大佬的腳本支持!${gl_bai} " + echo -e "${gl_hui}bin456789項目地址: https://github.com/bin456789/reinstall${gl_bai}" + echo -e "${gl_hui}leitbogioro項目地址: https://github.com/leitbogioro/Tools${gl_bai}" echo "------------------------" - echo "1. Debian 12 2. Debian 11" - echo "3. Debian 10 4. Debian 9" + echo "1. Debian 13 2. Debian 12" + echo "3. Debian 11 4. Debian 10" echo "------------------------" echo "11. Ubuntu 24.04 12. Ubuntu 22.04" echo "13. Ubuntu 20.04 14. Ubuntu 18.04" @@ -4547,39 +4986,42 @@ dd_xitong() { echo "35. openSUSE Tumbleweed 36. fnos飛牛公測版" echo "------------------------" echo "41. Windows 11 42. Windows 10" - echo "43. Windows 7 44. Windows Server 2022" - echo "45. Windows Server 2019 46. Windows Server 2016" + echo "43. Windows 7 44. Windows Server 2025" + echo "45. Windows Server 2022 46. Windows Server 2019" echo "47. Windows 11 ARM" echo "------------------------" echo "0. 返回上一級選單" echo "------------------------" read -e -p "請選擇要重裝的系統:" sys_choice case "$sys_choice" in + + 1) - send_stats "重裝debian 12" - dd_xitong_1 - bash InstallNET.sh -debian 12 + send_stats "重裝debian 13" + dd_xitong_3 + bash reinstall.sh debian 13 reboot exit ;; + 2) - send_stats "重裝debian 11" + send_stats "重裝debian 12" dd_xitong_1 - bash InstallNET.sh -debian 11 + bash InstallNET.sh -debian 12 reboot exit ;; 3) - send_stats "重裝debian 10" + send_stats "重裝debian 11" dd_xitong_1 - bash InstallNET.sh -debian 10 + bash InstallNET.sh -debian 11 reboot exit ;; 4) - send_stats "重裝debian 9" + send_stats "重裝debian 10" dd_xitong_1 - bash InstallNET.sh -debian 9 + bash InstallNET.sh -debian 10 reboot exit ;; @@ -4741,7 +5183,6 @@ dd_xitong() { exit ;; - 41) send_stats "重裝windows11" dd_xitong_2 @@ -4749,6 +5190,7 @@ dd_xitong() { reboot exit ;; + 42) dd_xitong_2 send_stats "重裝windows10" @@ -4756,6 +5198,7 @@ dd_xitong() { reboot exit ;; + 43) send_stats "重裝windows7" dd_xitong_4 @@ -4765,23 +5208,25 @@ dd_xitong() { ;; 44) - send_stats "重裝windows server 22" + send_stats "重裝windows server 25" dd_xitong_2 - bash InstallNET.sh -windows 2022 -lang "cn" + bash InstallNET.sh -windows 2025 -lang "cn" reboot exit ;; + 45) - send_stats "重裝windows server 19" + send_stats "重裝windows server 22" dd_xitong_2 - bash InstallNET.sh -windows 2019 -lang "cn" + bash InstallNET.sh -windows 2022 -lang "cn" reboot exit ;; + 46) - send_stats "重裝windows server 16" + send_stats "重裝windows server 19" dd_xitong_2 - bash InstallNET.sh -windows 2016 -lang "cn" + bash InstallNET.sh -windows 2019 -lang "cn" reboot exit ;; @@ -4874,7 +5319,6 @@ bbrv3() { echo "------------------------------------------------" echo "僅支持Debian/Ubuntu" echo "請備份數據,將為你升級Linux內核開啟BBR3" - echo "VPS是512M內存的,請提前添加1G虛擬內存,防止因內存不足失聯!" echo "------------------------------------------------" read -e -p "確定繼續嗎? (Y/N):" choice @@ -5076,7 +5520,7 @@ clamav_scan() { > /home/docker/clamav/log/scan.log > /dev/null 2>&1 # 執行 Docker 命令 - docker run -it --rm \ + docker run --rm \ --name clamav \ --mount source=clam_db,target=/var/lib/clamav \ $MOUNT_PARAMS \ @@ -5084,7 +5528,7 @@ clamav_scan() { clamav/clamav-debian:latest \ clamscan -r --log=/var/log/clamav/scan.log $SCAN_PARAMS - echo -e "${gl_lv}$@ 掃描完成,病毒報告存放在${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" + echo -e "${gl_lv}$@ 扫描完成,病毒报告存放在${gl_huang}/home/docker/clamav/log/scan.log${gl_bai}" echo -e "${gl_lv}如果有病毒請在${gl_huang}scan.log${gl_lv}文件中搜索FOUND關鍵字確認病毒位置${gl_bai}" } @@ -5339,7 +5783,7 @@ Kernel_optimize() { 1) cd ~ clear - local tiaoyou_moshi="高性能优化模式" + local tiaoyou_moshi="高性能優化模式" optimize_high_performance send_stats "高性能模式優化" ;; @@ -5358,14 +5802,14 @@ Kernel_optimize() { 4) cd ~ clear - local tiaoyou_moshi="直播优化模式" + local tiaoyou_moshi="直播優化模式" optimize_high_performance send_stats "直播推流優化" ;; 5) cd ~ clear - local tiaoyou_moshi="游戏服优化模式" + local tiaoyou_moshi="遊戲服優化模式" optimize_high_performance send_stats "遊戲服優化" ;; @@ -5553,9 +5997,9 @@ linux_trash() { local trash_status if ! grep -q "trash-put" "$bashrc_profile"; then - trash_status="${gl_hui}未启用${gl_bai}" + trash_status="${gl_hui}未啟用${gl_bai}" else - trash_status="${gl_lv}已启用${gl_bai}" + trash_status="${gl_lv}已啟用${gl_bai}" fi clear @@ -5611,7 +6055,10 @@ linux_trash() { done } - +linux_fav() { +send_stats "命令收藏夾" +bash <(curl -l -s ${gh_proxy}raw.githubusercontent.com/byJoey/cmdbox/refs/heads/main/install.sh) +} # 創建備份 create_backup() { @@ -6396,7 +6843,7 @@ rsync_manager() { -linux_ps() { +linux_info() { clear send_stats "系統信息查詢" @@ -6443,10 +6890,13 @@ linux_ps() { local swap_info=$(free -m | awk 'NR==3{used=$3; total=$2; if (total == 0) {percentage=0} else {percentage=used*100/total}; printf "%dM/%dM (%d%%)", used, total, percentage}') - local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1 % 3600) / 60); if (run_days > 0) printf("%d天 ", run_days); if (run_hours > 0) printf("%d时 ", run_hours); printf("%d分\n", run_minutes)}') + local runtime=$(cat /proc/uptime | awk -F. '{run_days=int($1 / 86400);run_hours=int(($1 % 86400) / 3600);run_minutes=int(($1% 3600) / 60); if (run_days > 0) printf("%d天 ", run_days); if (run_hours > 0) printf("%d時 ", run_hours); printf("%d分\n", run_minutes)}') local timezone=$(current_timezone) + local tcp_count=$(ss -t | wc -l) + local udp_count=$(ss -u | wc -l) + echo "" echo -e "系統信息查詢" @@ -6462,6 +6912,7 @@ linux_ps() { echo -e "${gl_kjlan}-------------" echo -e "${gl_kjlan}CPU佔用:${gl_bai}$cpu_usage_percent%" echo -e "${gl_kjlan}系統負載:${gl_bai}$load" + echo -e "${gl_kjlan}TCP|UDP連接數:${gl_bai}$tcp_count|$udp_count" echo -e "${gl_kjlan}物理內存:${gl_bai}$mem_info" echo -e "${gl_kjlan}虛擬內存:${gl_bai}$swap_info" echo -e "${gl_kjlan}硬盤佔用:${gl_bai}$disk_info" @@ -6508,7 +6959,7 @@ linux_tools() { echo -e "${gl_kjlan}11. ${gl_bai}btop 現代化監控工具${gl_huang}★${gl_bai} ${gl_kjlan}12. ${gl_bai}ranger 文件管理工具" echo -e "${gl_kjlan}13. ${gl_bai}ncdu 磁盤佔用查看工具${gl_kjlan}14. ${gl_bai}fzf 全局搜索工具" echo -e "${gl_kjlan}15. ${gl_bai}vim 文本編輯器${gl_kjlan}16. ${gl_bai}nano 文本編輯器${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系統" + echo -e "${gl_kjlan}17. ${gl_bai}git 版本控制系統${gl_kjlan}18. ${gl_bai}opencode AI編程助手${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}黑客帝國屏保${gl_kjlan}22. ${gl_bai}跑火車屏保" echo -e "${gl_kjlan}26. ${gl_bai}俄羅斯方塊小遊戲${gl_kjlan}27. ${gl_bai}貪吃蛇小遊戲" @@ -6667,6 +7118,17 @@ linux_tools() { send_stats "安裝git" ;; + 18) + clear + cd ~ + curl -fsSL https://opencode.ai/install | bash + source ~/.bashrc + source ~/.profile + opencode + send_stats "安裝opencode" + ;; + + 21) clear install cmatrix @@ -6695,6 +7157,7 @@ linux_tools() { nsnake send_stats "安裝nsnake" ;; + 28) clear install ninvaders @@ -6720,6 +7183,8 @@ linux_tools() { clear send_stats "全部卸載" remove htop iftop tmux ffmpeg btop ranger ncdu fzf cmatrix sl bastet nsnake ninvaders vim nano git + opencode uninstall + rm -rf ~/.opencode ;; 41) @@ -6777,7 +7242,7 @@ linux_bbr() { send_stats "alpine開啟bbr3" ;; 2) - sed -i '/net.ipv4.tcp_congestion_control=bbr/d' /etc/sysctl.conf + sed -i '/net.ipv4.tcp_congestion_control=/d' /etc/sysctl.conf sysctl -p server_reboot ;; @@ -6801,21 +7266,348 @@ linux_bbr() { -linux_docker() { +docker_ssh_migration() { - while true; do - clear - # send_stats "docker管理" - echo -e "Docker管理" - docker_tato - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}安裝更新Docker環境${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局狀態${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}4. ${gl_bai}Docker鏡像管理" - echo -e "${gl_kjlan}5. ${gl_bai}Docker網絡管理" + GREEN='\033[0;32m' + RED='\033[0;31m' + YELLOW='\033[1;33m' + BLUE='\033[0;36m' + NC='\033[0m' + + is_compose_container() { + local container=$1 + docker inspect "$container" | jq -e '.[0].Config.Labels["com.docker.compose.project"]' >/dev/null 2>&1 + } + + list_backups() { + local BACKUP_ROOT="/tmp" + echo -e "${BLUE}當前備份列表:${NC}" + ls -1dt ${BACKUP_ROOT}/docker_backup_* 2>/dev/null || echo "無備份" + } + + + + # ---------------------------- + # 備份 + # ---------------------------- + backup_docker() { + send_stats "Docker備份" + + echo -e "${YELLOW}正在備份 Docker 容器...${NC}" + docker ps --format '{{.Names}}' + read -e -p "請輸入要備份的容器名(多個空格分隔,回車備份全部運行中容器):" containers + + install tar jq gzip + install_docker + + local BACKUP_ROOT="/tmp" + local DATE_STR=$(date +%Y%m%d_%H%M%S) + local TARGET_CONTAINERS=() + if [ -z "$containers" ]; then + mapfile -t TARGET_CONTAINERS < <(docker ps --format '{{.Names}}') + else + read -ra TARGET_CONTAINERS <<< "$containers" + fi + [[ ${#TARGET_CONTAINERS[@]} -eq 0 ]] && { echo -e "${RED}沒有找到容器${NC}"; return; } + + local BACKUP_DIR="${BACKUP_ROOT}/docker_backup_${DATE_STR}" + mkdir -p "$BACKUP_DIR" + + local RESTORE_SCRIPT="${BACKUP_DIR}/docker_restore.sh" + echo "#!/bin/bash" > "$RESTORE_SCRIPT" + echo "set -e" >> "$RESTORE_SCRIPT" + echo "# 自動生成的還原腳本" >> "$RESTORE_SCRIPT" + + # 記錄已打包過的 Compose 項目路徑,避免重複打包 + declare -A PACKED_COMPOSE_PATHS=() + + for c in "${TARGET_CONTAINERS[@]}"; do + echo -e "${GREEN}備份容器:$c${NC}" + local inspect_file="${BACKUP_DIR}/${c}_inspect.json" + docker inspect "$c" > "$inspect_file" + + if is_compose_container "$c"; then + echo -e "${BLUE}檢測到$c是 docker-compose 容器${NC}" + local project_dir=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project.working_dir"] // empty') + local project_name=$(docker inspect "$c" | jq -r '.[0].Config.Labels["com.docker.compose.project"] // empty') + + if [ -z "$project_dir" ]; then + read -e -p "未檢測到 compose 目錄,請手動輸入路徑:" project_dir + fi + + # 如果該 Compose 項目已經打包過,跳過 + if [[ -n "${PACKED_COMPOSE_PATHS[$project_dir]}" ]]; then + echo -e "${YELLOW}Compose 項目 [$project_name] 已備份過,跳過重複打包...${NC}" + continue + fi + + if [ -f "$project_dir/docker-compose.yml" ]; then + echo "compose" > "${BACKUP_DIR}/backup_type_${project_name}" + echo "$project_dir" > "${BACKUP_DIR}/compose_path_${project_name}.txt" + tar -czf "${BACKUP_DIR}/compose_project_${project_name}.tar.gz" -C "$project_dir" . + echo "# docker-compose 恢復:$project_name" >> "$RESTORE_SCRIPT" + echo "cd \"$project_dir\" && docker compose up -d" >> "$RESTORE_SCRIPT" + PACKED_COMPOSE_PATHS["$project_dir"]=1 + echo -e "${GREEN}Compose 項目 [$project_name] 已打包:${project_dir}${NC}" + else + echo -e "${RED}未找到 docker-compose.yml,跳過此容器...${NC}" + fi + else + # 普通容器備份卷 + local VOL_PATHS + VOL_PATHS=$(docker inspect "$c" --format '{{range .Mounts}}{{.Source}} {{end}}') + for path in $VOL_PATHS; do + echo "打包卷:$path" + tar -czpf "${BACKUP_DIR}/${c}_$(basename $path).tar.gz" -C / "$(echo $path | sed 's/^\///')" + done + + # 端口 + local PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[] | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$inspect_file" 2>/dev/null) + for p in "${PORTS[@]}"; do PORT_ARGS+="-p $p "; done + + # 環境變量 + local ENV_VARS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[] | @sh' "$inspect_file") + for e in "${ENVS[@]}"; do ENV_VARS+="-e $e "; done + + # 卷映射 + local VOL_ARGS="" + for path in $VOL_PATHS; do VOL_ARGS+="-v $path:$path "; done + + # 鏡像 + local IMAGE + IMAGE=$(jq -r '.[0].Config.Image' "$inspect_file") + + echo -e "\n# 還原容器:$c" >> "$RESTORE_SCRIPT" + echo "docker run -d --name $c $PORT_ARGS $VOL_ARGS $ENV_VARS $IMAGE" >> "$RESTORE_SCRIPT" + fi + done + + + # 備份 /home/docker 下的所有文件(不含子目錄) + if [ -d "/home/docker" ]; then + echo -e "${BLUE}備份 /home/docker 下的文件...${NC}" + find /home/docker -maxdepth 1 -type f | tar -czf "${BACKUP_DIR}/home_docker_files.tar.gz" -T - + echo -e "${GREEN}/home/docker 下的文件已打包到:${BACKUP_DIR}/home_docker_files.tar.gz${NC}" + fi + + chmod +x "$RESTORE_SCRIPT" + echo -e "${GREEN}備份完成:${BACKUP_DIR}${NC}" + echo -e "${GREEN}可用還原腳本:${RESTORE_SCRIPT}${NC}" + + + } + + # ---------------------------- + # 還原 + # ---------------------------- + restore_docker() { + + send_stats "Docker還原" + read -e -p "請輸入要還原的備份目錄:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}備份目錄不存在${NC}"; return; } + + echo -e "${BLUE}開始執行還原操作...${NC}" + + install tar jq gzip + install_docker + + # --------- 優先還原 Compose 項目 --------- + for f in "$BACKUP_DIR"/backup_type_*; do + [[ ! -f "$f" ]] && continue + if grep -q "compose" "$f"; then + project_name=$(basename "$f" | sed 's/backup_type_//') + path_file="$BACKUP_DIR/compose_path_${project_name}.txt" + [[ -f "$path_file" ]] && original_path=$(cat "$path_file") || original_path="" + [[ -z "$original_path" ]] && read -e -p "未找到原始路徑,請輸入還原目錄路徑:" original_path + + # 檢查該 compose 項目的容器是否已經在運行 + running_count=$(docker ps --filter "label=com.docker.compose.project=$project_name" --format '{{.Names}}' | wc -l) + if [[ "$running_count" -gt 0 ]]; then + echo -e "${YELLOW}Compose 項目 [$project_name] 已有容器在運行,跳過還原...${NC}" + continue + fi + + read -e -p "確認還原 Compose 項目 [$project_name] 到路徑 [$original_path] ? (y/n): " confirm + [[ "$confirm" != "y" ]] && read -e -p "請輸入新的還原路徑:" original_path + + mkdir -p "$original_path" + tar -xzf "$BACKUP_DIR/compose_project_${project_name}.tar.gz" -C "$original_path" + echo -e "${GREEN}Compose 項目 [$project_name] 已解壓到:$original_path${NC}" + + cd "$original_path" || return + docker compose down || true + docker compose up -d + echo -e "${GREEN}Compose 項目 [$project_name] 還原完成!${NC}" + fi + done + + # --------- 繼續還原普通容器 --------- + echo -e "${BLUE}檢查並還原普通 Docker 容器...${NC}" + local has_container=false + for json in "$BACKUP_DIR"/*_inspect.json; do + [[ ! -f "$json" ]] && continue + has_container=true + container=$(basename "$json" | sed 's/_inspect.json//') + echo -e "${GREEN}處理容器:$container${NC}" + + # 檢查容器是否已經存在且正在運行 + if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 已在運行,跳過還原...${NC}" + continue + fi + + IMAGE=$(jq -r '.[0].Config.Image' "$json") + [[ -z "$IMAGE" || "$IMAGE" == "null" ]] && { echo -e "${RED}未找到鏡像信息,跳過:$container${NC}"; continue; } + + # 端口映射 + PORT_ARGS="" + mapfile -t PORTS < <(jq -r '.[0].HostConfig.PortBindings | to_entries[]? | "\(.value[0].HostPort):\(.key | split("/")[0])"' "$json") + for p in "${PORTS[@]}"; do + [[ -n "$p" ]] && PORT_ARGS="$PORT_ARGS -p $p" + done + + # 環境變量 + ENV_ARGS="" + mapfile -t ENVS < <(jq -r '.[0].Config.Env[]' "$json") + for e in "${ENVS[@]}"; do + ENV_ARGS="$ENV_ARGS -e \"$e\"" + done + + # 卷映射 + 卷數據恢復 + VOL_ARGS="" + mapfile -t VOLS < <(jq -r '.[0].Mounts[] | "\(.Source):\(.Destination)"' "$json") + for v in "${VOLS[@]}"; do + VOL_SRC=$(echo "$v" | cut -d':' -f1) + VOL_DST=$(echo "$v" | cut -d':' -f2) + mkdir -p "$VOL_SRC" + VOL_ARGS="$VOL_ARGS -v $VOL_SRC:$VOL_DST" + + VOL_FILE="$BACKUP_DIR/${container}_$(basename $VOL_SRC).tar.gz" + if [[ -f "$VOL_FILE" ]]; then + echo "恢復卷數據:$VOL_SRC" + tar -xzf "$VOL_FILE" -C / + fi + done + + # 刪除已存在但未運行的容器 + if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then + echo -e "${YELLOW}容器 [$container] 存在但未運行,刪除舊容器...${NC}" + docker rm -f "$container" + fi + + # 啟動容器 + echo "執行還原命令: docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + eval "docker run -d --name \"$container\" $PORT_ARGS $VOL_ARGS $ENV_ARGS \"$IMAGE\"" + done + + [[ "$has_container" == false ]] && echo -e "${YELLOW}未找到普通容器的備份信息${NC}" + + # 還原 /home/docker 下的文件 + if [ -f "$BACKUP_DIR/home_docker_files.tar.gz" ]; then + echo -e "${BLUE}正在還原 /home/docker 下的文件...${NC}" + mkdir -p /home/docker + tar -xzf "$BACKUP_DIR/home_docker_files.tar.gz" -C / + echo -e "${GREEN}/home/docker 下的文件已還原完成${NC}" + else + echo -e "${YELLOW}未找到 /home/docker 下文件的備份,跳過...${NC}" + fi + + + } + + + # ---------------------------- + # 遷移 + # ---------------------------- + migrate_docker() { + send_stats "Docker遷移" + install jq + read -e -p "請輸入要遷移的備份目錄:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}備份目錄不存在${NC}"; return; } + + read -e -p "目標服務器IP:" TARGET_IP + read -e -p "目標服務器SSH用戶名:" TARGET_USER + read -e -p "目標服務器SSH端口 [默認22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} + + local LATEST_TAR="$BACKUP_DIR" + + echo -e "${YELLOW}傳輸備份中...${NC}" + if [[ -z "$TARGET_PASS" ]]; then + # 使用密鑰登錄 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no -r "$LATEST_TAR" "$TARGET_USER@$TARGET_IP:/tmp/" + fi + + } + + # ---------------------------- + # 刪除備份 + # ---------------------------- + delete_backup() { + send_stats "Docker備份文件刪除" + read -e -p "請輸入要刪除的備份目錄:" BACKUP_DIR + [[ ! -d "$BACKUP_DIR" ]] && { echo -e "${RED}備份目錄不存在${NC}"; return; } + rm -rf "$BACKUP_DIR" + echo -e "${GREEN}已刪除備份:${BACKUP_DIR}${NC}" + } + + # ---------------------------- + # 主菜單 + # ---------------------------- + main_menu() { + send_stats "Docker備份遷移還原" + while true; do + clear + echo "------------------------" + echo -e "Docker備份/遷移/還原工具" + echo "------------------------" + list_backups + echo -e "" + echo "------------------------" + echo -e "1. 備份docker項目" + echo -e "2. 遷移docker項目" + echo -e "3. 還原docker項目" + echo -e "4. 刪除docker項目的備份文件" + echo "------------------------" + echo -e "0. 返回上一級菜單" + echo "------------------------" + read -e -p "請選擇:" choice + case $choice in + 1) backup_docker ;; + 2) migrate_docker ;; + 3) restore_docker ;; + 4) delete_backup ;; + 0) return ;; + *) echo -e "${RED}無效選項${NC}" ;; + esac + break_end + done + } + + main_menu +} + + + + + +linux_docker() { + + while true; do + clear + # send_stats "docker管理" + echo -e "Docker管理" + docker_tato + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}安裝更新Docker環境${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}2. ${gl_bai}查看Docker全局狀態${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}3. ${gl_bai}Docker容器管理${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}4. ${gl_bai}Docker鏡像管理" + echo -e "${gl_kjlan}5. ${gl_bai}Docker網絡管理" echo -e "${gl_kjlan}6. ${gl_bai}Docker捲管理" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}7. ${gl_bai}清理無用的docker容器和鏡像網絡數據卷" @@ -6826,6 +7618,7 @@ linux_docker() { echo -e "${gl_kjlan}11. ${gl_bai}開啟Docker-ipv6訪問" echo -e "${gl_kjlan}12. ${gl_bai}關閉Docker-ipv6訪問" echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}19. ${gl_bai}備份/遷移/還原Docker環境" echo -e "${gl_kjlan}20. ${gl_bai}卸載Docker環境" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜單" @@ -6884,7 +7677,7 @@ linux_docker() { echo "------------------------------------------------------------" container_ids=$(docker ps -q) - printf "%-25s %-25s %-25s\n" "容器名称" "网络名称" "IP地址" + printf "%-25s %-25s %-25s\n" "容器名稱" "網絡名稱" "IP地址" for container_id in $container_ids; do local container_info=$(docker inspect --format '{{ .Name }}{{ range $network, $config := .NetworkSettings.Networks }} {{ $network }} {{ $config.IPAddress }}{{ end }}' "$container_id") @@ -7033,6 +7826,9 @@ linux_docker() { restart docker ;; + + + 11) clear send_stats "Docker v6 開" @@ -7045,6 +7841,11 @@ linux_docker() { docker_ipv6_off ;; + 19) + docker_ssh_migration + ;; + + 20) clear send_stats "Docker卸載" @@ -7114,6 +7915,7 @@ linux_test() { echo -e "${gl_kjlan}綜合性測試" echo -e "${gl_kjlan}31. ${gl_bai}bench 性能測試" echo -e "${gl_kjlan}32. ${gl_bai}spiritysdx 融合怪測評${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${gl_bai}nodequality 融合怪測評${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜單" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -7231,9 +8033,17 @@ linux_test() { 32) send_stats "spiritysdx融合怪測評" clear - curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + curl -L ${gh_proxy}gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh && chmod +x ecs.sh && bash ecs.sh + ;; + + 33) + send_stats "nodequality融合怪測評" + clear + bash <(curl -sL https://run.NodeQuality.com) ;; + + 0) kejilion @@ -7300,7 +8110,7 @@ linux_Oracle() { local speedtest_interval=${speedtest_interval:-$DEFAULT_SPEEDTEST_INTERVAL} # 運行Docker容器 - docker run -itd --name=lookbusy --restart=always \ + docker run -d --name=lookbusy --restart=always \ -e TZ=Asia/Shanghai \ -e CPU_UTIL="$cpu_util" \ -e CPU_CORE="$cpu_core" \ @@ -7368,7 +8178,8 @@ linux_Oracle() { 4) clear - echo "該功能處於開發階段,敬請期待!" + send_stats "R探長開機腳本" + bash <(wget -qO- ${gh_proxy}github.com/Yohann0617/oci-helper/releases/latest/download/sh_oci-helper_install.sh) ;; 5) clear @@ -7398,6 +8209,9 @@ linux_Oracle() { } + + + docker_tato() { local container_count=$(docker ps -a -q 2>/dev/null | wc -l) @@ -7415,20 +8229,20 @@ docker_tato() { ldnmp_tato() { local cert_count=$(ls /home/web/certs/*_cert.pem 2>/dev/null | wc -l) -local output="站点: ${gl_lv}${cert_count}${gl_bai}" +local output="${gl_lv}${cert_count}${gl_bai}" local dbrootpasswd=$(grep -oP 'MYSQL_ROOT_PASSWORD:\s*\K.*' /home/web/docker-compose.yml 2>/dev/null | tr -d '[:space:]') if [ -n "$dbrootpasswd" ]; then local db_count=$(docker exec mysql mysql -u root -p"$dbrootpasswd" -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "Database|information_schema|mysql|performance_schema|sys" | wc -l) fi -local db_output="数据库: ${gl_lv}${db_count}${gl_bai}" +local db_output="${gl_lv}${db_count}${gl_bai}" if command -v docker &>/dev/null; then if docker ps --filter "name=nginx" --filter "status=running" | grep -q nginx; then echo -e "${gl_huang}------------------------" - echo -e "${gl_lv}環境已安裝${gl_bai} $output $db_output" + echo -e "${gl_lv}環境已安裝${gl_bai}站點:$output資料庫:$db_output" fi fi @@ -7470,7 +8284,7 @@ linux_ldnmp() { echo -e "${gl_huang}23. ${gl_bai}站點反向代理-IP+端口${gl_huang}★${gl_bai} ${gl_huang}24. ${gl_bai}站點反向代理-域名" echo -e "${gl_huang}25. ${gl_bai}安裝Bitwarden密碼管理平台${gl_huang}26. ${gl_bai}安裝Halo博客網站" echo -e "${gl_huang}27. ${gl_bai}安裝AI繪畫提示詞生成器${gl_huang}28. ${gl_bai}站點反向代理-負載均衡" - echo -e "${gl_huang}30. ${gl_bai}自定義靜態站點" + echo -e "${gl_huang}29. ${gl_bai}Stream四層代理轉發${gl_huang}30. ${gl_bai}自定義靜態站點" echo -e "${gl_huang}------------------------" echo -e "${gl_huang}31. ${gl_bai}站點數據管理${gl_huang}★${gl_bai} ${gl_huang}32. ${gl_bai}備份全站數據" echo -e "${gl_huang}33. ${gl_bai}定時遠程備份${gl_huang}34. ${gl_bai}還原全站數據" @@ -7495,24 +8309,29 @@ linux_ldnmp() { 3) clear # Discuz論壇 - webname="Discuz论坛" + webname="Discuz論壇" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/discuz.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html mkdir $yuming cd $yuming - wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20240520.zip + wget -O latest.zip ${gh_proxy}github.com/kejilion/Website_source_code/raw/main/Discuz_X3.5_SC_UTF8_20250901.zip unzip latest.zip rm latest.zip @@ -7538,12 +8357,15 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/kdy.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7567,18 +8389,22 @@ linux_ldnmp() { 5) clear # 蘋果CMS - webname="苹果CMS" + webname="蘋果CMS" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/maccms.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7610,18 +8436,22 @@ linux_ldnmp() { 6) clear # 獨腳數卡 - webname="独脚数卡" + webname="獨腳數卡" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/dujiaoka.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + + nginx_http_on cd /home/web/html @@ -7658,18 +8488,21 @@ linux_ldnmp() { 7) clear # flarum論壇 - webname="flarum论坛" + webname="flarum論壇" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/flarum.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on docker exec php rm -f /usr/local/etc/php/conf.d/optimized_php.ini @@ -7690,9 +8523,13 @@ linux_ldnmp() { docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/sitemap" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/oauth" docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/best-answer:*" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/upload" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/gamification" + docker exec php sh -c "cd /var/www/html/$yuming && composer require fof/byobu:*" docker exec php sh -c "cd /var/www/html/$yuming && composer require v17development/flarum-seo" docker exec php sh -c "cd /var/www/html/$yuming && composer require clarkwinkelmann/flarum-ext-emojionearea" + restart_ldnmp @@ -7715,12 +8552,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/typecho.com.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7753,13 +8594,16 @@ linux_ldnmp() { add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/refs/heads/main/index_php.conf sed -i "s|/var/www/html/yuming.com/|/var/www/html/yuming.com/linkstack|g" /home/web/conf.d/$yuming.conf sed -i "s|yuming.com|$yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7783,18 +8627,21 @@ linux_ldnmp() { 20) clear - webname="PHP动态站点" + webname="PHP動態站點" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming ldnmp_install_status - install_ssltls - certs_status - add_db + wget -O /home/web/conf.d/map.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/map.conf wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/index_php.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + add_db + nginx_http_on cd /home/web/html @@ -7917,18 +8764,21 @@ linux_ldnmp() { 22) clear - webname="站点重定向" + webname="站點重定向" send_stats "安裝$webname" echo "開始部署$webname" add_yuming read -e -p "請輸入跳轉域名:" reverseproxy nginx_install_status - install_ssltls - certs_status + wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/rewrite.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s/baidu.com/$reverseproxy/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7960,12 +8810,14 @@ linux_ldnmp() { echo -e "域名格式:${gl_huang}google.com${gl_bai}" read -e -p "請輸入你的反代域名:" fandai_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/reverse-proxy-domain.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf sed -i "s|fandaicom|$fandai_yuming|g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on docker exec nginx nginx -s reload @@ -7981,20 +8833,17 @@ linux_ldnmp() { send_stats "安裝$webname" echo "開始部署$webname" add_yuming - nginx_install_status - install_ssltls - certs_status docker run -d \ --name bitwarden \ - --restart always \ + --restart=always \ -p 3280:80 \ -v /home/web/html/$yuming/bitwarden/data:/data \ vaultwarden/server + duankou=3280 - reverse_proxy + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou - nginx_web_on ;; @@ -8004,30 +8853,28 @@ linux_ldnmp() { send_stats "安裝$webname" echo "開始部署$webname" add_yuming - nginx_install_status - install_ssltls - certs_status - docker run -d --name halo --restart always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - duankou=8010 - reverse_proxy + docker run -d --name halo --restart=always -p 8010:8090 -v /home/web/html/$yuming/.halo2:/root/.halo2 halohub/halo:2 - nginx_web_on + duankou=8010 + ldnmp_Proxy ${yuming} 127.0.0.1 $duankou ;; 27) clear - webname="AI绘画提示词生成器" + webname="AI繪畫提示詞生成器" send_stats "安裝$webname" echo "開始部署$webname" add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8050,19 +8897,25 @@ linux_ldnmp() { ;; + 29) + stream_panel + ;; + 30) clear - webname="静态站点" + webname="靜態站點" send_stats "安裝$webname" echo "開始部署$webname" add_yuming repeat_add_yuming nginx_install_status - install_ssltls - certs_status wget -O /home/web/conf.d/$yuming.conf ${gh_proxy}raw.githubusercontent.com/kejilion/nginx/main/html.conf sed -i "s/yuming.com/$yuming/g" /home/web/conf.d/$yuming.conf + + install_ssltls + certs_status + nginx_http_on cd /home/web/html @@ -8127,6 +8980,8 @@ linux_ldnmp() { case "$choice" in [Yy]) read -e -p "請輸入遠端服務器IP:" remote_ip + read -e -p "目標服務器SSH端口 [默認22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} if [ -z "$remote_ip" ]; then echo "錯誤: 請輸入遠端服務器IP。" continue @@ -8135,7 +8990,7 @@ linux_ldnmp() { if [ -n "$latest_tar" ]; then ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" sleep 2 # 添加等待时间 - scp -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/home/" echo "文件已傳送至遠程服務器home目錄。" else echo "未找到要傳送的文件。" @@ -8216,7 +9071,6 @@ linux_ldnmp() { echo -e "${gl_huang}正在解壓$filename ...${gl_bai}" cd /home/ && tar -xzf "$filename" - check_port install_dependency install_docker install_certbot @@ -8340,7 +9194,6 @@ linux_ldnmp() { docker images --filter=reference="$ldnmp_pods*" -q | xargs docker rmi > /dev/null 2>&1 docker compose up -d --force-recreate $ldnmp_pods docker restart $ldnmp_pods > /dev/null 2>&1 - restart_redis send_stats "更新$ldnmp_pods" echo "更新${ldnmp_pods}完成" @@ -8353,7 +9206,6 @@ linux_ldnmp() { cd /home/web/ docker compose down --rmi all - check_port install_dependency install_docker install_certbot @@ -8411,2231 +9263,3868 @@ linux_ldnmp() { linux_panel() { - while true; do - clear - # send_stats "應用市場" - echo -e "應用市場" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}1. ${gl_bai}寶塔面板官方版${gl_kjlan}2. ${gl_bai}aaPanel寶塔國際版" - echo -e "${gl_kjlan}3. ${gl_bai}1Panel新一代管理面板${gl_kjlan}4. ${gl_bai}NginxProxyManager可視化面板" - echo -e "${gl_kjlan}5. ${gl_bai}OpenList多存儲文件列表程序${gl_kjlan}6. ${gl_bai}Ubuntu遠程桌面網頁版" - echo -e "${gl_kjlan}7. ${gl_bai}哪吒探針VPS監控面板${gl_kjlan}8. ${gl_bai}QB離線BT磁力下載面板" - echo -e "${gl_kjlan}9. ${gl_bai}Poste.io郵件服務器程序${gl_kjlan}10. ${gl_bai}RocketChat多人在線聊天系統" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}11. ${gl_bai}禪道項目管理軟件${gl_kjlan}12. ${gl_bai}青龍面板定時任務管理平台" - echo -e "${gl_kjlan}13. ${gl_bai}Cloudreve網盤${gl_huang}★${gl_bai} ${gl_kjlan}14. ${gl_bai}簡單圖床圖片管理程序" - echo -e "${gl_kjlan}15. ${gl_bai}emby多媒體管理系統${gl_kjlan}16. ${gl_bai}Speedtest測速面板" - echo -e "${gl_kjlan}17. ${gl_bai}AdGuardHome去廣告軟件${gl_kjlan}18. ${gl_bai}onlyoffice在線辦公OFFICE" - echo -e "${gl_kjlan}19. ${gl_bai}雷池WAF防火牆面板${gl_kjlan}20. ${gl_bai}portainer容器管理面板" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}21. ${gl_bai}VScode網頁版${gl_kjlan}22. ${gl_bai}UptimeKuma監控工具" - echo -e "${gl_kjlan}23. ${gl_bai}Memos網頁備忘錄${gl_kjlan}24. ${gl_bai}Webtop遠程桌面網頁版${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}25. ${gl_bai}Nextcloud網盤${gl_kjlan}26. ${gl_bai}QD-Today定時任務管理框架" - echo -e "${gl_kjlan}27. ${gl_bai}Dockge容器堆棧管理面板${gl_kjlan}28. ${gl_bai}LibreSpeed測速工具" - echo -e "${gl_kjlan}29. ${gl_bai}searxng聚合搜索站${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}PhotoPrism私有相冊系統" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}31. ${gl_bai}StirlingPDF工具大全${gl_kjlan}32. ${gl_bai}drawio免費的在線圖表軟件${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}33. ${gl_bai}Sun-Panel導航面板${gl_kjlan}34. ${gl_bai}Pingvin-Share文件分享平台" - echo -e "${gl_kjlan}35. ${gl_bai}極簡朋友圈${gl_kjlan}36. ${gl_bai}LobeChatAI聊天聚合網站" - echo -e "${gl_kjlan}37. ${gl_bai}MyIP工具箱${gl_huang}★${gl_bai} ${gl_kjlan}38. ${gl_bai}小雅alist全家桶" - echo -e "${gl_kjlan}39. ${gl_bai}Bililive直播錄製工具${gl_kjlan}40. ${gl_bai}webssh網頁版SSH連接工具" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}41. ${gl_bai}耗子管理面板${gl_kjlan}42. ${gl_bai}Nexterm遠程連接工具" - echo -e "${gl_kjlan}43. ${gl_bai}RustDesk遠程桌面(服務端)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${gl_bai}RustDesk遠程桌面(中繼端)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}45. ${gl_bai}Docker加速站${gl_kjlan}46. ${gl_bai}GitHub加速站${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}47. ${gl_bai}普羅米修斯監控${gl_kjlan}48. ${gl_bai}普羅米修斯(主機監控)" - echo -e "${gl_kjlan}49. ${gl_bai}普羅米修斯(容器監控)${gl_kjlan}50. ${gl_bai}補貨監控工具" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}51. ${gl_bai}PVE開小雞面板${gl_kjlan}52. ${gl_bai}DPanel容器管理面板" - echo -e "${gl_kjlan}53. ${gl_bai}llama3聊天AI大模型${gl_kjlan}54. ${gl_bai}AMH主機建站管理面板" - echo -e "${gl_kjlan}55. ${gl_bai}FRP內網穿透(服務端)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${gl_bai}FRP內網穿透(客戶端)${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}57. ${gl_bai}Deepseek聊天AI大模型${gl_kjlan}58. ${gl_bai}Dify大模型知識庫${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}59. ${gl_bai}NewAPI大模型資產管理${gl_kjlan}60. ${gl_bai}JumpServer開源堡壘機" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}61. ${gl_bai}在線翻譯服務器${gl_kjlan}62. ${gl_bai}RAGFlow大模型知識庫" - echo -e "${gl_kjlan}63. ${gl_bai}OpenWebUI自託管AI平台${gl_huang}★${gl_bai} ${gl_kjlan}64. ${gl_bai}it-tools工具箱" - echo -e "${gl_kjlan}65. ${gl_bai}n8n自動化工作流平台${gl_huang}★${gl_bai} ${gl_kjlan}66. ${gl_bai}yt-dlp視頻下載工具" - echo -e "${gl_kjlan}67. ${gl_bai}ddns-go動態DNS管理工具${gl_huang}★${gl_bai} ${gl_kjlan}68. ${gl_bai}AllinSSL證書管理平台" - echo -e "${gl_kjlan}69. ${gl_bai}SFTPGo文件傳輸工具${gl_kjlan}70. ${gl_bai}AstrBot聊天機器人框架" - echo -e "${gl_kjlan}------------------------" - echo -e "${gl_kjlan}71. ${gl_bai}Navidrome私有音樂服務器${gl_kjlan}72. ${gl_bai}bitwarden密碼管理器${gl_huang}★${gl_bai}" - echo -e "${gl_kjlan}73. ${gl_bai}LibreTV私有影視${gl_kjlan}74. ${gl_bai}MoonTV私有影視" - echo -e "${gl_kjlan}75. ${gl_bai}Melody音樂精靈${gl_kjlan}76. ${gl_bai}在線DOS老遊戲" - echo -e "${gl_kjlan}77. ${gl_bai}迅雷離線下載工具${gl_kjlan}78. ${gl_bai}PandaWiki智能文檔管理系統" - echo -e "${gl_kjlan}79. ${gl_bai}Beszel服務器監控" +local sub_choice="$1" + +clear +cd ~ +install git +if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git +else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 +fi + +while true; do + + if [ -z "$sub_choice" ]; then + clear + echo -e "應用市場" + echo -e "${gl_kjlan}-------------------------" + + local app_numbers=$([ -f /home/docker/appno.txt ] && cat /home/docker/appno.txt || echo "") + + # 用循環設置顏色 + for i in {1..150}; do + if echo "$app_numbers" | grep -q "^$i$"; then + declare "color$i=${gl_lv}" + else + declare "color$i=${gl_bai}" + fi + done + + echo -e "${gl_kjlan}1. ${color1}寶塔面板官方版${gl_kjlan}2. ${color2}aaPanel寶塔國際版" + echo -e "${gl_kjlan}3. ${color3}1Panel新一代管理面板${gl_kjlan}4. ${color4}NginxProxyManager可視化面板" + echo -e "${gl_kjlan}5. ${color5}OpenList多存儲文件列表程序${gl_kjlan}6. ${color6}Ubuntu遠程桌面網頁版" + echo -e "${gl_kjlan}7. ${color7}哪吒探針VPS監控面板${gl_kjlan}8. ${color8}QB離線BT磁力下載面板" + echo -e "${gl_kjlan}9. ${color9}Poste.io郵件服務器程序${gl_kjlan}10. ${color10}RocketChat多人在線聊天系統" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}11. ${color11}禪道項目管理軟件${gl_kjlan}12. ${color12}青龍面板定時任務管理平台" + echo -e "${gl_kjlan}13. ${color13}Cloudreve網盤${gl_huang}★${gl_bai} ${gl_kjlan}14. ${color14}簡單圖床圖片管理程序" + echo -e "${gl_kjlan}15. ${color15}emby多媒體管理系統${gl_kjlan}16. ${color16}Speedtest測速面板" + echo -e "${gl_kjlan}17. ${color17}AdGuardHome去廣告軟件${gl_kjlan}18. ${color18}onlyoffice在線辦公OFFICE" + echo -e "${gl_kjlan}19. ${color19}雷池WAF防火牆面板${gl_kjlan}20. ${color20}portainer容器管理面板" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}21. ${color21}VScode網頁版${gl_kjlan}22. ${color22}UptimeKuma監控工具" + echo -e "${gl_kjlan}23. ${color23}Memos網頁備忘錄${gl_kjlan}24. ${color24}Webtop遠程桌面網頁版${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}25. ${color25}Nextcloud網盤${gl_kjlan}26. ${color26}QD-Today定時任務管理框架" + echo -e "${gl_kjlan}27. ${color27}Dockge容器堆棧管理面板${gl_kjlan}28. ${color28}LibreSpeed測速工具" + echo -e "${gl_kjlan}29. ${color29}searxng聚合搜索站${gl_huang}★${gl_bai} ${gl_kjlan}30. ${color30}PhotoPrism私有相冊系統" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}31. ${color31}StirlingPDF工具大全${gl_kjlan}32. ${color32}drawio免費的在線圖表軟件${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}33. ${color33}Sun-Panel導航面板${gl_kjlan}34. ${color34}Pingvin-Share文件分享平台" + echo -e "${gl_kjlan}35. ${color35}極簡朋友圈${gl_kjlan}36. ${color36}LobeChatAI聊天聚合網站" + echo -e "${gl_kjlan}37. ${color37}MyIP工具箱${gl_huang}★${gl_bai} ${gl_kjlan}38. ${color38}小雅alist全家桶" + echo -e "${gl_kjlan}39. ${color39}Bililive直播錄製工具${gl_kjlan}40. ${color40}webssh網頁版SSH連接工具" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}41. ${color41}耗子管理面板${gl_kjlan}42. ${color42}Nexterm遠程連接工具" + echo -e "${gl_kjlan}43. ${color43}RustDesk遠程桌面(服務端)${gl_huang}★${gl_bai} ${gl_kjlan}44. ${color44}RustDesk遠程桌面(中繼端)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}45. ${color45}Docker加速站${gl_kjlan}46. ${color46}GitHub加速站${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}47. ${color47}普羅米修斯監控${gl_kjlan}48. ${color48}普羅米修斯(主機監控)" + echo -e "${gl_kjlan}49. ${color49}普羅米修斯(容器監控)${gl_kjlan}50. ${color50}補貨監控工具" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}51. ${color51}PVE開小雞面板${gl_kjlan}52. ${color52}DPanel容器管理面板" + echo -e "${gl_kjlan}53. ${color53}llama3聊天AI大模型${gl_kjlan}54. ${color54}AMH主機建站管理面板" + echo -e "${gl_kjlan}55. ${color55}FRP內網穿透(服務端)${gl_huang}★${gl_bai} ${gl_kjlan}56. ${color56}FRP內網穿透(客戶端)${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}57. ${color57}Deepseek聊天AI大模型${gl_kjlan}58. ${color58}Dify大模型知識庫${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}59. ${color59}NewAPI大模型資產管理${gl_kjlan}60. ${color60}JumpServer開源堡壘機" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}61. ${color61}在線翻譯服務器${gl_kjlan}62. ${color62}RAGFlow大模型知識庫" + echo -e "${gl_kjlan}63. ${color63}OpenWebUI自託管AI平台${gl_huang}★${gl_bai} ${gl_kjlan}64. ${color64}it-tools工具箱" + echo -e "${gl_kjlan}65. ${color65}n8n自動化工作流平台${gl_huang}★${gl_bai} ${gl_kjlan}66. ${color66}yt-dlp視頻下載工具" + echo -e "${gl_kjlan}67. ${color67}ddns-go動態DNS管理工具${gl_huang}★${gl_bai} ${gl_kjlan}68. ${color68}AllinSSL證書管理平台" + echo -e "${gl_kjlan}69. ${color69}SFTPGo文件傳輸工具${gl_kjlan}70. ${color70}AstrBot聊天機器人框架" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}71. ${color71}Navidrome私有音樂服務器${gl_kjlan}72. ${color72}bitwarden密碼管理器${gl_huang}★${gl_bai}" + echo -e "${gl_kjlan}73. ${color73}LibreTV私有影視${gl_kjlan}74. ${color74}MoonTV私有影視" + echo -e "${gl_kjlan}75. ${color75}Melody音樂精靈${gl_kjlan}76. ${color76}在線DOS老遊戲" + echo -e "${gl_kjlan}77. ${color77}迅雷離線下載工具${gl_kjlan}78. ${color78}PandaWiki智能文檔管理系統" + echo -e "${gl_kjlan}79. ${color79}Beszel服務器監控${gl_kjlan}80. ${color80}linkwarden書籤管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}81. ${color81}JitsiMeet視頻會議${gl_kjlan}82. ${color82}gpt-load高性能AI透明代理" + echo -e "${gl_kjlan}83. ${color83}komari服務器監控工具${gl_kjlan}84. ${color84}Wallos個人財務管理工具" + echo -e "${gl_kjlan}85. ${color85}immich圖片視頻管理器${gl_kjlan}86. ${color86}jellyfin媒體管理系統" + echo -e "${gl_kjlan}87. ${color87}SyncTV一起看片神器${gl_kjlan}88. ${color88}Owncast自託管直播平台" + echo -e "${gl_kjlan}89. ${color89}FileCodeBox文件快遞${gl_kjlan}90. ${color90}matrix去中心化聊天協議" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}91. ${color91}gitea私有代碼倉庫${gl_kjlan}92. ${color92}FileBrowser文件管理器" + echo -e "${gl_kjlan}93. ${color93}Dufs極簡靜態文件服務器${gl_kjlan}94. ${color94}Gopeed高速下載工具" + echo -e "${gl_kjlan}95. ${color95}paperless文檔管理平台${gl_kjlan}96. ${color96}2FAuth自託管二步驗證器" + echo -e "${gl_kjlan}97. ${color97}WireGuard組網(服務端)${gl_kjlan}98. ${color98}WireGuard組網(客戶端)" + echo -e "${gl_kjlan}99. ${color99}DSM群暉虛擬機${gl_kjlan}100. ${color100}Syncthing點對點文件同步工具" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}101. ${color101}AI視頻生成工具${gl_kjlan}102. ${color102}VoceChat多人在線聊天系統" + echo -e "${gl_kjlan}103. ${color103}Umami網站統計工具${gl_kjlan}104. ${color104}Stream四層代理轉發工具" + echo -e "${gl_kjlan}105. ${color105}思源筆記${gl_kjlan}106. ${color106}Drawnix開源白板工具" + echo -e "${gl_kjlan}107. ${color107}PanSou網盤搜索${gl_kjlan}108. ${color108}LangBot聊天機器人" + echo -e "${gl_kjlan}109. ${color109}ZFile在線網盤${gl_kjlan}110. ${color110}Karakeep書籤管理" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}111. ${color111}多格式文件轉換工具${gl_kjlan}112. ${color112}Lucky大內網穿透工具" + echo -e "${gl_kjlan}113. ${color113}Firefox瀏覽器" + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}第三方應用列表" + echo -e "${gl_kjlan}想要讓你的應用出現在這裡?查看開發者指南:${gl_huang}https://dev.kejilion.sh/${gl_bai}" + + for f in "$HOME"/apps/*.conf; do + [ -e "$f" ] || continue + local base_name=$(basename "$f" .conf) + # 獲取應用描述 + local app_text=$(grep "app_text=" "$f" | cut -d'=' -f2 | tr -d '"' | tr -d "'") + + # 檢查安裝狀態 (匹配 appno.txt 中的 ID) + # 這裡假設 appno.txt 中記錄的是 base_name (即文件名) + if echo "$app_numbers" | grep -q "^$base_name$"; then + # 如果已安裝:顯示 base_name - 描述 [已安裝] (綠色) + echo -e "${gl_kjlan}$base_name${gl_bai} - ${gl_lv}$app_text[已安裝]${gl_bai}" + else + # 如果未安裝:正常顯示 + echo -e "${gl_kjlan}$base_name${gl_bai} - $app_text" + fi + done + + + + echo -e "${gl_kjlan}-------------------------" + echo -e "${gl_kjlan}b. ${gl_bai}備份全部應用數據${gl_kjlan}r. ${gl_bai}還原全部應用數據" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}0. ${gl_bai}返回主菜單" echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "請輸入你的選擇:" sub_choice + fi - case $sub_choice in - 1) - - local lujing="[ -d "/www/server/panel" ]" - local panelname="宝塔面板" - local panelurl="https://www.bt.cn/new/index.html" - - panel_app_install() { - if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec - } - - panel_app_manage() { - bt - } + case $sub_choice in + 1|bt|baota) + local app_id="1" + local lujing="[ -d "/www/server/panel" ]" + local panelname="寶塔面板" + local panelurl="https://www.bt.cn/new/index.html" + + panel_app_install() { + if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec + } - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_manage() { + bt + } - install_panel + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } + install_panel - ;; - 2) - local lujing="[ -d "/www/server/panel" ]" - local panelname="aapanel" - local panelurl="https://www.aapanel.com/new/index.html" + ;; + 2|aapanel) - panel_app_install() { - URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel - } - panel_app_manage() { - bt - } + local app_id="2" + local lujing="[ -d "/www/server/panel" ]" + local panelname="aapanel" + local panelurl="https://www.aapanel.com/new/index.html" - panel_app_uninstall() { - curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh - chmod +x bt-uninstall.sh - ./bt-uninstall.sh - } + panel_app_install() { + URL=https://www.aapanel.com/script/install_7.0_en.sh && if [ -f /usr/bin/curl ];then curl -ksSO "$URL" ;else wget --no-check-certificate -O install_7.0_en.sh "$URL";fi;bash install_7.0_en.sh aapanel + } - install_panel + panel_app_manage() { + bt + } - ;; - 3) + panel_app_uninstall() { + curl -o bt-uninstall.sh http://download.bt.cn/install/bt-uninstall.sh > /dev/null 2>&1 && chmod +x bt-uninstall.sh && ./bt-uninstall.sh + chmod +x bt-uninstall.sh + ./bt-uninstall.sh + } - local lujing="command -v 1pctl" - local panelname="1Panel" - local panelurl="https://1panel.cn/" + install_panel - panel_app_install() { - install bash - bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" - } + ;; + 3|1p|1panel) - panel_app_manage() { - 1pctl user-info - 1pctl update password - } + local app_id="3" + local lujing="command -v 1pctl" + local panelname="1Panel" + local panelurl="https://1panel.cn/" - panel_app_uninstall() { - 1pctl uninstall - } + panel_app_install() { + install bash + bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)" + } - install_panel + panel_app_manage() { + 1pctl user-info + 1pctl update password + } - ;; - 4) + panel_app_uninstall() { + 1pctl uninstall + } - local docker_name="npm" - local docker_img="jc21/nginx-proxy-manager:latest" - local docker_port=81 + install_panel - docker_rum() { + ;; + 4|npm) - docker run -d \ - --name=$docker_name \ - -p ${docker_port}:81 \ - -p 80:80 \ - -p 443:443 \ - -v /home/docker/npm/data:/data \ - -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ - --restart=always \ - $docker_img + local app_id="4" + local docker_name="npm" + local docker_img="jc21/nginx-proxy-manager:latest" + local docker_port=81 + docker_rum() { - } + docker run -d \ + --name=$docker_name \ + -p ${docker_port}:81 \ + -p 80:80 \ + -p 443:443 \ + -v /home/docker/npm/data:/data \ + -v /home/docker/npm/letsencrypt:/etc/letsencrypt \ + --restart=always \ + $docker_img - local docker_describe="一个Nginx反向代理工具面板,不支持添加域名访问。" - local docker_url="官网介绍: https://nginxproxymanager.com/" - local docker_use="echo \"初始用户名: admin@example.com\"" - local docker_passwd="echo \"初始密码: changeme\"" - local app_size="1" - docker_app + } - ;; + local docker_describe="一個Nginx反向代理工具面板,不支持添加域名訪問。" + local docker_url="官網介紹: https://nginxproxymanager.com/" + local docker_use="echo \"初始用戶名: admin@example.com\"" + local docker_passwd="echo \"初始密碼: changeme\"" + local app_size="1" - 5) + docker_app - local docker_name="openlist" - local docker_img="openlistteam/openlist:latest-aria2" - local docker_port=5244 + ;; - docker_rum() { + 5|openlist) - docker run -d \ - --restart=always \ - -v /home/docker/openlist:/opt/openlist/data \ - -p ${docker_port}:5244 \ - -e PUID=0 \ - -e PGID=0 \ - -e UMASK=022 \ - --name="openlist" \ - openlistteam/openlist:latest-aria2 + local app_id="5" + local docker_name="openlist" + local docker_img="openlistteam/openlist:latest-aria2" + local docker_port=5244 - } + docker_rum() { + mkdir -p /home/docker/openlist + chmod -R 777 /home/docker/openlist - local docker_describe="一个支持多种存储,支持网页浏览和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驱动" - local docker_url="官网介绍: https://github.com/OpenListTeam/OpenList" - local docker_use="docker exec -it openlist ./openlist admin random" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --restart=always \ + -v /home/docker/openlist:/opt/openlist/data \ + -p ${docker_port}:5244 \ + -e PUID=0 \ + -e PGID=0 \ + -e UMASK=022 \ + --name="openlist" \ + openlistteam/openlist:latest-aria2 - ;; + } - 6) - local docker_name="webtop-ubuntu" - local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" - local docker_port=3006 + local docker_describe="一個支持多種存儲,支持網頁瀏覽和 WebDAV 的文件列表程序,由 gin 和 Solidjs 驅動" + local docker_url="官網介紹: https://github.com/OpenListTeam/OpenList" + local docker_use="docker exec openlist ./openlist admin random" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; + 6|webtop-ubuntu) + + local app_id="6" + local docker_name="webtop-ubuntu" + local docker_img="lscr.io/linuxserver/webtop:ubuntu-kde" + local docker_port=3006 + + docker_rum() { + + read -e -p "設置登錄用戶名:" admin + read -e -p "設置登錄用戶密碼:" admin_password + docker run -d \ + --name=webtop-ubuntu \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:ubuntu-kde - docker run -d \ - --name=webtop-ubuntu \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=ubuntu-abc \ - -e PASSWORD=ubuntuABC123 \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:ubuntu-kde + } - } + local docker_describe="webtop基於Ubuntu的容器。若IP無法訪問,請添加域名訪問。" + local docker_url="官網介紹: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - local docker_describe="webtop基于Ubuntu的容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: ubuntu-abc\"" - local docker_passwd="echo \"密码: ubuntuABC123\"" - local app_size="2" - docker_app + ;; + 7|nezha) + clear + send_stats "搭建哪吒" - ;; - 7) + local app_id="7" + local docker_name="nezha-dashboard" + local docker_port=8008 + while true; do + check_docker_app + check_docker_image_update $docker_name clear - send_stats "搭建哪吒" - local docker_name="nezha-dashboard" - local docker_port=8008 - while true; do - check_docker_app - check_docker_image_update $docker_name - clear - echo -e "哪吒監控$check_docker $update_status" - echo "開源、輕量、易用的服務器監控與運維工具" - echo "官網搭建文檔: https://nezha.wiki/guide/dashboard.html" - if docker inspect "$docker_name" &>/dev/null; then + echo -e "哪吒監控$check_docker $update_status" + echo "開源、輕量、易用的服務器監控與運維工具" + echo "官網搭建文檔: https://nezha.wiki/guide/dashboard.html" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) + check_docker_app_ip + fi + echo "" + echo "------------------------" + echo "1. 使用" + echo "------------------------" + echo "0. 返回上一級選單" + echo "------------------------" + read -e -p "輸入你的選擇:" choice + + case $choice in + 1) + check_disk_space 1 + install unzip jq + install_docker + curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) check_docker_app_ip - fi - echo "" - echo "------------------------" - echo "1. 使用" - echo "------------------------" - echo "0. 返回上一級選單" - echo "------------------------" - read -e -p "輸入你的選擇:" choice + ;; - case $choice in - 1) - check_disk_space 1 - install unzip jq - install_docker - curl -sL ${gh_proxy}raw.githubusercontent.com/nezhahq/scripts/refs/heads/main/install.sh -o nezha.sh && chmod +x nezha.sh && ./nezha.sh - local docker_port=$(docker port $docker_name | awk -F'[:]' '/->/ {print $NF}' | uniq) - check_docker_app_ip - ;; + *) + break + ;; - *) - break - ;; + esac + break_end + done + ;; - esac - break_end - done - ;; + 8|qb|QB) + + local app_id="8" + local docker_name="qbittorrent" + local docker_img="lscr.io/linuxserver/qbittorrent:latest" + local docker_port=8081 + + docker_rum() { + + docker run -d \ + --name=qbittorrent \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e WEBUI_PORT=${docker_port} \ + -e TORRENTING_PORT=56881 \ + -p ${docker_port}:${docker_port} \ + -p 56881:56881 \ + -p 56881:56881/udp \ + -v /home/docker/qbittorrent/config:/config \ + -v /home/docker/qbittorrent/downloads:/downloads \ + --restart=always \ + lscr.io/linuxserver/qbittorrent:latest - 8) + } - local docker_name="qbittorrent" - local docker_img="lscr.io/linuxserver/qbittorrent:latest" - local docker_port=8081 + local docker_describe="qbittorrent離線BT磁力下載服務" + local docker_url="官網介紹: https://hub.docker.com/r/linuxserver/qbittorrent" + local docker_use="sleep 3" + local docker_passwd="docker logs qbittorrent" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d \ - --name=qbittorrent \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e WEBUI_PORT=${docker_port} \ - -e TORRENTING_PORT=56881 \ - -p ${docker_port}:${docker_port} \ - -p 56881:56881 \ - -p 56881:56881/udp \ - -v /home/docker/qbittorrent/config:/config \ - -v /home/docker/qbittorrent/downloads:/downloads \ - --restart unless-stopped \ - lscr.io/linuxserver/qbittorrent:latest + 9|mail) + send_stats "搭建郵局" + clear + install telnet + local app_id="9" + local docker_name=“mailserver” + while true; do + check_docker_app + check_docker_image_update $docker_name - } + clear + echo -e "郵局服務$check_docker $update_status" + echo "poste.io 是一個開源的郵件服務器解決方案," + echo "視頻介紹: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" - local docker_describe="qbittorrent离线BT磁力下载服务" - local docker_url="官网介绍: https://hub.docker.com/r/linuxserver/qbittorrent" - local docker_use="sleep 3" - local docker_passwd="docker logs qbittorrent" - local app_size="1" - docker_app + echo "" + echo "端口檢測" + port=25 + timeout=3 + if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then + echo -e "${gl_lv}端口$port當前可用${gl_bai}" + else + echo -e "${gl_hong}端口$port當前不可用${gl_bai}" + fi + echo "" - ;; + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + yuming=$(cat /home/docker/mail.txt) + echo "訪問地址:" + echo "https://$yuming" + fi - 9) - send_stats "搭建郵局" - clear - install telnet - local docker_name=“mailserver” - while true; do - check_docker_app - check_docker_image_update $docker_name + echo "------------------------" + echo "1. 安裝 2. 更新 3. 卸載" + echo "------------------------" + echo "0. 返回上一級選單" + echo "------------------------" + read -e -p "輸入你的選擇:" choice - clear - echo -e "郵局服務$check_docker $update_status" - echo "poste.io 是一個開源的郵件服務器解決方案," - echo "視頻介紹: https://www.bilibili.com/video/BV1wv421C71t?t=0.1" + case $choice in + 1) + setup_docker_dir + check_disk_space 2 /home/docker + read -e -p "請設置郵箱域名 例如 mail.yuming.com :" yuming + mkdir -p /home/docker + echo "$yuming" > /home/docker/mail.txt + echo "------------------------" + ip_address + echo "先解析這些DNS記錄" + echo "A mail $ipv4_address" + echo "CNAME imap $yuming" + echo "CNAME pop $yuming" + echo "CNAME smtp $yuming" + echo "MX @ $yuming" + echo "TXT @ v=spf1 mx ~all" + echo "TXT ? ?" + echo "" + echo "------------------------" + echo "按任意鍵繼續..." + read -n 1 -s -r -p "" + + install jq + install_docker - echo "" - echo "端口檢測" - port=25 - timeout=3 - if echo "quit" | timeout $timeout telnet smtp.qq.com $port | grep 'Connected'; then - echo -e "${gl_lv}端口$port當前可用${gl_bai}" - else - echo -e "${gl_hong}端口$port當前不可用${gl_bai}" - fi - echo "" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.io + + + add_app_id + + clear + echo "poste.io已經安裝完成" + echo "------------------------" + echo "您可以使用以下地址訪問poste.io:" + echo "https://$yuming" + echo "" - if docker inspect "$docker_name" &>/dev/null; then + ;; + + 2) + docker rm -f mailserver + docker rmi -f analogic/poste.i yuming=$(cat /home/docker/mail.txt) - echo "訪問地址:" + docker run \ + --net=host \ + -e TZ=Europe/Prague \ + -v /home/docker/mail:/data \ + --name "mailserver" \ + -h "$yuming" \ + --restart=always \ + -d analogic/poste.i + + + add_app_id + + clear + echo "poste.io已經安裝完成" + echo "------------------------" + echo "您可以使用以下地址訪問poste.io:" echo "https://$yuming" - fi + echo "" + ;; + 3) + docker rm -f mailserver + docker rmi -f analogic/poste.io + rm /home/docker/mail.txt + rm -rf /home/docker/mail + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "應用已卸載" + ;; - echo "------------------------" - echo "1. 安裝 2. 更新 3. 卸載" - echo "------------------------" - echo "0. 返回上一級選單" - echo "------------------------" - read -e -p "輸入你的選擇:" choice + *) + break + ;; - case $choice in - 1) - check_disk_space 2 - read -e -p "請設置郵箱域名 例如 mail.yuming.com :" yuming - mkdir -p /home/docker - echo "$yuming" > /home/docker/mail.txt - echo "------------------------" - ip_address - echo "先解析這些DNS記錄" - echo "A mail $ipv4_address" - echo "CNAME imap $yuming" - echo "CNAME pop $yuming" - echo "CNAME smtp $yuming" - echo "MX @ $yuming" - echo "TXT @ v=spf1 mx ~all" - echo "TXT ? ?" - echo "" - echo "------------------------" - echo "按任意鍵繼續..." - read -n 1 -s -r -p "" + esac + break_end + done - install jq - install_docker + ;; - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.io + 10|rocketchat) - clear - echo "poste.io已經安裝完成" - echo "------------------------" - echo "您可以使用以下地址訪問poste.io:" - echo "https://$yuming" - echo "" + local app_id="10" + local app_name="Rocket.Chat聊天系統" + local app_text="Rocket.Chat 是一個開源的團隊通訊平台,支持實時聊天、音視頻通話、文件共享等多種功能," + local app_url="官方介紹: https://www.rocket.chat/" + local docker_name="rocketchat" + local docker_port="3897" + local app_size="2" - ;; + docker_app_install() { + docker run --name db -d --restart=always \ + -v /home/docker/mongo/dump:/dump \ + mongo:latest --replSet rs5 --oplogSize 256 + sleep 1 + docker exec db mongosh --eval "printjson(rs.initiate())" + sleep 5 + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - 2) - docker rm -f mailserver - docker rmi -f analogic/poste.i - yuming=$(cat /home/docker/mail.txt) - docker run \ - --net=host \ - -e TZ=Europe/Prague \ - -v /home/docker/mail:/data \ - --name "mailserver" \ - -h "$yuming" \ - --restart=always \ - -d analogic/poste.i - clear - echo "poste.io已經安裝完成" - echo "------------------------" - echo "您可以使用以下地址訪問poste.io:" - echo "https://$yuming" - echo "" - ;; - 3) - docker rm -f mailserver - docker rmi -f analogic/poste.io - rm /home/docker/mail.txt - rm -rf /home/docker/mail - echo "應用已卸載" - ;; + clear + ip_address + echo "已經安裝完成" + check_docker_app_ip + } - *) - break - ;; + docker_app_update() { + docker rm -f rocketchat + docker rmi -f rocket.chat:latest + docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat + clear + ip_address + echo "rocket.chat已經安裝完成" + check_docker_app_ip + } - esac - break_end - done + docker_app_uninstall() { + docker rm -f rocketchat + docker rmi -f rocket.chat + docker rm -f db + docker rmi -f mongo:latest + rm -rf /home/docker/mongo + echo "應用已卸載" + } - ;; + docker_app_plus + ;; - 10) - local app_name="Rocket.Chat聊天系统" - local app_text="Rocket.Chat 是一个开源的团队通讯平台,支持实时聊天、音视频通话、文件共享等多种功能," - local app_url="官方介绍: https://www.rocket.chat/" - local docker_name="rocketchat" - local docker_port="3897" - local app_size="2" - - docker_app_install() { - docker run --name db -d --restart=always \ - -v /home/docker/mongo/dump:/dump \ - mongo:latest --replSet rs5 --oplogSize 256 - sleep 1 - docker exec -it db mongosh --eval "printjson(rs.initiate())" - sleep 5 - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "已經安裝完成" - check_docker_app_ip - } + 11|zentao) + local app_id="11" + local docker_name="zentao-server" + local docker_img="idoop/zentao:latest" + local docker_port=82 - docker_app_update() { - docker rm -f rocketchat - docker rmi -f rocket.chat:latest - docker run --name rocketchat --restart=always -p ${docker_port}:3000 --link db --env ROOT_URL=http://localhost --env MONGO_OPLOG_URL=mongodb://db:27017/rs5 -d rocket.chat - clear - ip_address - echo "rocket.chat已經安裝完成" - check_docker_app_ip - } - - docker_app_uninstall() { - docker rm -f rocketchat - docker rmi -f rocket.chat - docker rm -f db - docker rmi -f mongo:latest - rm -rf /home/docker/mongo - echo "應用已卸載" - } - docker_app_plus - ;; + docker_rum() { + docker run -d -p ${docker_port}:80 \ + -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ + -e BIND_ADDRESS="false" \ + -v /home/docker/zentao-server/:/opt/zbox/ \ + --add-host smtp.exmail.qq.com:163.177.90.125 \ + --name zentao-server \ + --restart=always \ + idoop/zentao:latest - 11) - local docker_name="zentao-server" - local docker_img="idoop/zentao:latest" - local docker_port=82 + } - docker_rum() { + local docker_describe="禪道是通用的項目管理軟件" + local docker_url="官網介紹: https://www.zentao.net/" + local docker_use="echo \"初始用戶名: admin\"" + local docker_passwd="echo \"初始密碼: 123456\"" + local app_size="2" + docker_app + ;; - docker run -d -p ${docker_port}:80 \ - -e ADMINER_USER="root" -e ADMINER_PASSWD="password" \ - -e BIND_ADDRESS="false" \ - -v /home/docker/zentao-server/:/opt/zbox/ \ - --add-host smtp.exmail.qq.com:163.177.90.125 \ - --name zentao-server \ - --restart=always \ - idoop/zentao:latest + 12|qinglong) + local app_id="12" + local docker_name="qinglong" + local docker_img="whyour/qinglong:latest" + local docker_port=5700 + docker_rum() { - } - local docker_describe="禅道是通用的项目管理软件" - local docker_url="官网介绍: https://www.zentao.net/" - local docker_use="echo \"初始用户名: admin\"" - local docker_passwd="echo \"初始密码: 123456\"" - local app_size="2" - docker_app + docker run -d \ + -v /home/docker/qinglong/data:/ql/data \ + -p ${docker_port}:5700 \ + --name qinglong \ + --hostname qinglong \ + --restart=always \ + whyour/qinglong:latest - ;; - 12) - local docker_name="qinglong" - local docker_img="whyour/qinglong:latest" - local docker_port=5700 + } + + local docker_describe="青龍面板是一個定時任務管理平台" + local docker_url="官網介紹:${gh_proxy}github.com/whyour/qinglong" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + 13|cloudreve) + + local app_id="13" + local app_name="cloudreve網盤" + local app_text="cloudreve是一個支持多家云存儲的網盤系統" + local app_url="視頻介紹: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" + local docker_name="cloudreve" + local docker_port="5212" + local app_size="2" + + docker_app_install() { + cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 + curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml + sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml + cd /home/docker/cloud/ + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - docker_rum() { + docker_app_update() { + cd /home/docker/cloud/ && docker compose down --rmi all + cd /home/docker/cloud/ && docker compose up -d + } - docker run -d \ - -v /home/docker/qinglong/data:/ql/data \ - -p ${docker_port}:5700 \ - --name qinglong \ - --hostname qinglong \ - --restart unless-stopped \ - whyour/qinglong:latest + docker_app_uninstall() { + cd /home/docker/cloud/ && docker compose down --rmi all + rm -rf /home/docker/cloud + echo "應用已卸載" + } - } + docker_app_plus + ;; - local docker_describe="青龙面板是一个定时任务管理平台" - local docker_url="官网介绍: ${gh_proxy}github.com/whyour/qinglong" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + 14|easyimage) + local app_id="14" + local docker_name="easyimage" + local docker_img="ddsderek/easyimage:latest" + local docker_port=8014 + docker_rum() { + + docker run -d \ + --name easyimage \ + -p ${docker_port}:80 \ + -e TZ=Asia/Shanghai \ + -e PUID=1000 \ + -e PGID=1000 \ + -v /home/docker/easyimage/config:/app/web/config \ + -v /home/docker/easyimage/i:/app/web/i \ + --restart=always \ + ddsderek/easyimage:latest - ;; - 13) + } - local app_name="cloudreve网盘" - local app_text="cloudreve是一个支持多家云存储的网盘系统" - local app_url="视频介绍: https://www.bilibili.com/video/BV13F4m1c7h7?t=0.1" - local docker_name="cloudreve" - local docker_port="5212" - local app_size="2" - - docker_app_install() { - cd /home/ && mkdir -p docker/cloud && cd docker/cloud && mkdir temp_data && mkdir -vp cloudreve/{uploads,avatar} && touch cloudreve/conf.ini && touch cloudreve/cloudreve.db && mkdir -p aria2/config && mkdir -p data/aria2 && chmod -R 777 data/aria2 - curl -o /home/docker/cloud/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/cloudreve-docker-compose.yml - sed -i "s/5212:5212/${docker_port}:5212/g" /home/docker/cloud/docker-compose.yml - cd /home/docker/cloud/ - docker compose up -d - clear - echo "已經安裝完成" - check_docker_app_ip - } + local docker_describe="簡單圖床是一個簡單的圖床程序" + local docker_url="官網介紹:${gh_proxy}github.com/icret/EasyImages2.0" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + 15|emby) + local app_id="15" + local docker_name="emby" + local docker_img="linuxserver/emby:latest" + local docker_port=8015 - docker_app_update() { - cd /home/docker/cloud/ && docker compose down --rmi all - cd /home/docker/cloud/ && docker compose up -d - } + docker_rum() { + docker run -d --name=emby --restart=always \ + -v /home/docker/emby/config:/config \ + -v /home/docker/emby/share1:/mnt/share1 \ + -v /home/docker/emby/share2:/mnt/share2 \ + -v /mnt/notify:/mnt/notify \ + -p ${docker_port}:8096 \ + -e UID=1000 -e GID=100 -e GIDLIST=100 \ + linuxserver/emby:latest - docker_app_uninstall() { - cd /home/docker/cloud/ && docker compose down --rmi all - rm -rf /home/docker/cloud - echo "應用已卸載" - } + } - docker_app_plus - ;; - 14) - local docker_name="easyimage" - local docker_img="ddsderek/easyimage:latest" - local docker_port=85 - docker_rum() { - - docker run -d \ - --name easyimage \ - -p ${docker_port}:80 \ - -e TZ=Asia/Shanghai \ - -e PUID=1000 \ - -e PGID=1000 \ - -v /home/docker/easyimage/config:/app/web/config \ - -v /home/docker/easyimage/i:/app/web/i \ - --restart unless-stopped \ - ddsderek/easyimage:latest - - } - - local docker_describe="简单图床是一个简单的图床程序" - local docker_url="官网介绍: ${gh_proxy}github.com/icret/EasyImages2.0" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="emby是一個主從式架構的媒體服務器軟件,可以用來整理服務器上的視頻和音頻,並將音頻和視頻流式傳輸到客戶端設備" + local docker_url="官網介紹: https://emby.media/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 15) - local docker_name="emby" - local docker_img="linuxserver/emby:latest" - local docker_port=8096 + 16|looking) + local app_id="16" + local docker_name="looking-glass" + local docker_img="wikihostinc/looking-glass-server" + local docker_port=8016 + + + docker_rum() { + + docker run -d --name looking-glass --restart=always -p ${docker_port}:80 wikihostinc/looking-glass-server + + } + + local docker_describe="Speedtest測速面板是一個VPS網速測試工具,多項測試功能,還可以實時監控VPS進出站流量" + local docker_url="官網介紹:${gh_proxy}github.com/wikihost-opensource/als" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + 17|adguardhome) + + local app_id="17" + local docker_name="adguardhome" + local docker_img="adguard/adguardhome" + local docker_port=8017 + + docker_rum() { + + docker run -d \ + --name adguardhome \ + -v /home/docker/adguardhome/work:/opt/adguardhome/work \ + -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ + -p 53:53/tcp \ + -p 53:53/udp \ + -p ${docker_port}:3000/tcp \ + --restart=always \ + adguard/adguardhome + + + } + + + local docker_describe="AdGuardHome是一款全網廣告攔截與反跟踪軟件,未來將不止是一個DNS服務器。" + local docker_url="官網介紹: https://hub.docker.com/r/adguard/adguardhome" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + 18|onlyoffice) + + local app_id="18" + local docker_name="onlyoffice" + local docker_img="onlyoffice/documentserver" + local docker_port=8018 + + docker_rum() { + + docker run -d -p ${docker_port}:80 \ + --restart=always \ + --name onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ + -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ + onlyoffice/documentserver + + + } + + local docker_describe="onlyoffice是一款開源的在線office工具,太強大了!" + local docker_url="官網介紹: https://www.onlyoffice.com/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + + ;; + + 19|safeline) + send_stats "搭建雷池" + + local app_id="19" + local docker_name=safeline-mgt + local docker_port=9443 + while true; do + check_docker_app + clear + echo -e "雷池服務$check_docker" + echo "雷池是長亭科技開發的WAF站點防火牆程序面板,可以反代站點進行自動化防禦" + echo "視頻介紹: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" + if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q "$docker_name"; then + check_docker_app_ip + fi + echo "" + + echo "------------------------" + echo "1. 安裝 2. 更新 3. 重置密碼 4. 卸載" + echo "------------------------" + echo "0. 返回上一級選單" + echo "------------------------" + read -e -p "輸入你的選擇:" choice + + case $choice in + 1) + install_docker + check_disk_space 5 + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" + + add_app_id + clear + echo "雷池WAF面板已經安裝完成" + check_docker_app_ip + docker exec safeline-mgt resetadmin + + ;; + + 2) + bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" + docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') + echo "" + + add_app_id + clear + echo "雷池WAF面板已經更新完成" + check_docker_app_ip + ;; + 3) + docker exec safeline-mgt resetadmin + ;; + 4) + cd /data/safeline + docker compose down --rmi all + + sed -i "/\b${app_id}\b/d" /home/docker/appno.txt + echo "如果你是默認安裝目錄那現在項目已經卸載。如果你是自定義安裝目錄你需要到安裝目錄下自行執行:" + echo "docker compose down && docker compose down --rmi all" + ;; + *) + break + ;; + + esac + break_end + done + + ;; + + 20|portainer) + local app_id="20" + local docker_name="portainer" + local docker_img="portainer/portainer" + local docker_port=8020 + + docker_rum() { + + docker run -d \ + --name portainer \ + -p ${docker_port}:9000 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/portainer:/data \ + --restart=always \ + portainer/portainer + + } + + + local docker_describe="portainer是一個輕量級的docker容器管理面板" + local docker_url="官網介紹: https://www.portainer.io/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + 21|vscode) + local app_id="21" + local docker_name="vscode-web" + local docker_img="codercom/code-server" + local docker_port=8021 + + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart=always codercom/code-server + + } + + + local docker_describe="VScode是一款強大的在線代碼編寫工具" + local docker_url="官網介紹:${gh_proxy}github.com/coder/code-server" + local docker_use="sleep 3" + local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" + local app_size="1" + docker_app + ;; + + + 22|uptime-kuma) + local app_id="22" + local docker_name="uptime-kuma" + local docker_img="louislam/uptime-kuma:latest" + local docker_port=8022 + + + docker_rum() { + + docker run -d \ + --name=uptime-kuma \ + -p ${docker_port}:3001 \ + -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ + --restart=always \ + louislam/uptime-kuma:latest + + } + + + local docker_describe="Uptime Kuma 易於使用的自託管監控工具" + local docker_url="官網介紹:${gh_proxy}github.com/louislam/uptime-kuma" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 23|memos) + local app_id="23" + local docker_name="memos" + local docker_img="neosmemo/memos:stable" + local docker_port=8023 + + docker_rum() { + + docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart=always neosmemo/memos:stable + + } + + local docker_describe="Memos是一款輕量級、自託管的備忘錄中心" + local docker_url="官網介紹:${gh_proxy}github.com/usememos/memos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 24|webtop) + local app_id="24" + local docker_name="webtop" + local docker_img="lscr.io/linuxserver/webtop:latest" + local docker_port=8024 + + docker_rum() { + + read -e -p "設置登錄用戶名:" admin + read -e -p "設置登錄用戶密碼:" admin_password + docker run -d \ + --name=webtop \ + --security-opt seccomp=unconfined \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SUBFOLDER=/ \ + -e TITLE=Webtop \ + -e CUSTOM_USER=${admin} \ + -e PASSWORD=${admin_password} \ + -e LC_ALL=zh_CN.UTF-8 \ + -e DOCKER_MODS=linuxserver/mods:universal-package-install \ + -e INSTALL_PACKAGES=font-noto-cjk \ + -p ${docker_port}:3000 \ + -v /home/docker/webtop/data:/config \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --shm-size="1gb" \ + --restart=always \ + lscr.io/linuxserver/webtop:latest + + } + + + local docker_describe="webtop基於Alpine的中文版容器。若IP無法訪問,請添加域名訪問。" + local docker_url="官網介紹: https://docs.linuxserver.io/images/docker-webtop/" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 25|nextcloud) + local app_id="25" + local docker_name="nextcloud" + local docker_img="nextcloud:latest" + local docker_port=8025 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + + } + + local docker_describe="Nextcloud擁有超過 400,000 個部署,是您可以下載的最受歡迎的本地內容協作平台" + local docker_url="官網介紹: https://nextcloud.com/" + local docker_use="echo \"賬號: nextcloud 密碼:$rootpasswd\"" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 26|qd) + local app_id="26" + local docker_name="qd" + local docker_img="qdtoday/qd:latest" + local docker_port=8026 + + docker_rum() { + + docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + + } + + local docker_describe="QD-Today是一個HTTP請求定時任務自動執行框架" + local docker_url="官網介紹: https://qd-today.github.io/qd/zh_CN/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 27|dockge) + local app_id="27" + local docker_name="dockge" + local docker_img="louislam/dockge:latest" + local docker_port=8027 + + docker_rum() { + + docker run -d --name dockge --restart=always -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + + } + + local docker_describe="dockge是一個可視化的docker-compose容器管理面板" + local docker_url="官網介紹:${gh_proxy}github.com/louislam/dockge" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 28|speedtest) + local app_id="28" + local docker_name="speedtest" + local docker_img="ghcr.io/librespeed/speedtest" + local docker_port=8028 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 --name speedtest --restart=always ghcr.io/librespeed/speedtest + + } + + local docker_describe="librespeed是用Javascript實現的輕量級速度測試工具,即開即用" + local docker_url="官網介紹:${gh_proxy}github.com/librespeed/speedtest" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 29|searxng) + local app_id="29" + local docker_name="searxng" + local docker_img="searxng/searxng" + local docker_port=8029 + + docker_rum() { + + docker run -d \ + --name searxng \ + --restart=always \ + -p ${docker_port}:8080 \ + -v "/home/docker/searxng:/etc/searxng" \ + searxng/searxng + + } + + local docker_describe="searxng是一個私有且隱私的搜索引擎站點" + local docker_url="官網介紹: https://hub.docker.com/r/alandoyle/searxng" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 30|photoprism) + local app_id="30" + local docker_name="photoprism" + local docker_img="photoprism/photoprism:latest" + local docker_port=8030 + local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + + docker_rum() { + + docker run -d \ + --name photoprism \ + --restart=always \ + --security-opt seccomp=unconfined \ + --security-opt apparmor=unconfined \ + -p ${docker_port}:2342 \ + -e PHOTOPRISM_UPLOAD_NSFW="true" \ + -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ + -v /home/docker/photoprism/storage:/photoprism/storage \ + -v /home/docker/photoprism/Pictures:/photoprism/originals \ + photoprism/photoprism + + } + + + local docker_describe="photoprism非常強大的私有相冊系統" + local docker_url="官網介紹: https://www.photoprism.app/" + local docker_use="echo \"賬號: admin 密碼:$rootpasswd\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 31|s-pdf) + local app_id="31" + local docker_name="s-pdf" + local docker_img="frooodle/s-pdf:latest" + local docker_port=8031 + + docker_rum() { + + docker run -d \ + --name s-pdf \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ + -v /home/docker/s-pdf/extraConfigs:/configs \ + -v /home/docker/s-pdf/logs:/logs \ + -e DOCKER_ENABLE_SECURITY=false \ + frooodle/s-pdf:latest + } + + local docker_describe="這是一個強大的本地託管基於 Web 的 PDF 操作工具,使用 docker,允許您對 PDF 文件執行各種操作,例如拆分合併、轉換、重新組織、添加圖像、旋轉、壓縮等。" + local docker_url="官網介紹:${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 32|drawio) + local app_id="32" + local docker_name="drawio" + local docker_img="jgraph/drawio" + local docker_port=8032 + + docker_rum() { + + docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + + } + + + local docker_describe="這是一個強大圖表繪製軟件。思維導圖,拓撲圖,流程圖,都能畫" + local docker_url="官網介紹: https://www.drawio.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 33|sun-panel) + local app_id="33" + local docker_name="sun-panel" + local docker_img="hslr/sun-panel" + local docker_port=8033 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:3002 \ + -v /home/docker/sun-panel/conf:/app/conf \ + -v /home/docker/sun-panel/uploads:/app/uploads \ + -v /home/docker/sun-panel/database:/app/database \ + --name sun-panel \ + hslr/sun-panel + + } + + local docker_describe="Sun-Panel服務器、NAS導航面板、Homepage、瀏覽器首頁" + local docker_url="官網介紹: https://doc.sun-panel.top/zh_cn/" + local docker_use="echo \"賬號: admin@sun.cc 密碼: 12345678\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 34|pingvin-share) + local app_id="34" + local docker_name="pingvin-share" + local docker_img="stonith404/pingvin-share" + local docker_port=8034 + + docker_rum() { + + docker run -d \ + --name pingvin-share \ + --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/pingvin-share/data:/opt/app/backend/data \ + stonith404/pingvin-share + } + + local docker_describe="Pingvin Share 是一個可自建的文件分享平台,是 WeTransfer 的一個替代品" + local docker_url="官網介紹:${gh_proxy}github.com/stonith404/pingvin-share" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 35|moments) + local app_id="35" + local docker_name="moments" + local docker_img="kingwrcy/moments:latest" + local docker_port=8035 + + docker_rum() { + + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/moments/data:/app/data \ + -v /etc/localtime:/etc/localtime:ro \ + -v /etc/timezone:/etc/timezone:ro \ + --name moments \ + kingwrcy/moments:latest + } + + + local docker_describe="極簡朋友圈,高仿微信朋友圈,記錄你的美好生活" + local docker_url="官網介紹:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" + local docker_use="echo \"賬號: admin 密碼: a123456\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + + 36|lobe-chat) + local app_id="36" + local docker_name="lobe-chat" + local docker_img="lobehub/lobe-chat:latest" + local docker_port=8036 + + docker_rum() { + + docker run -d -p ${docker_port}:3210 \ + --name lobe-chat \ + --restart=always \ + lobehub/lobe-chat + } + + local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" + local docker_url="官網介紹:${gh_proxy}github.com/lobehub/lobe-chat" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 37|myip) + local app_id="37" + local docker_name="myip" + local docker_img="jason5ng32/myip:latest" + local docker_port=8037 + + docker_rum() { + + docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + + } + + + local docker_describe="是一個多功能IP工具箱,可以查看自己IP信息及連通性,用網頁面板呈現" + local docker_url="官網介紹:${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 38|xiaoya) + send_stats "小雅全家桶" + clear + install_docker + check_disk_space 1 + bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" + ;; + + 39|bililive) + + if [ ! -d /home/docker/bililive-go/ ]; then + mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 + wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 + fi + + local app_id="39" + local docker_name="bililive-go" + local docker_img="chigusa/bililive-go" + local docker_port=8039 + + docker_rum() { + + docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + + } + + local docker_describe="Bililive-go是一個支持多種直播平台的直播錄製工具" + local docker_url="官網介紹:${gh_proxy}github.com/hr3lxphr6j/bililive-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 40|webssh) + local app_id="40" + local docker_name="webssh" + local docker_img="jrohy/webssh" + local docker_port=8040 + docker_rum() { + docker run -d -p ${docker_port}:5032 --restart=always --name webssh -e TZ=Asia/Shanghai jrohy/webssh + } + + local docker_describe="簡易在線ssh連接工具和sftp工具" + local docker_url="官網介紹:${gh_proxy}github.com/Jrohy/webssh" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 41|haozi) + + local app_id="41" + local lujing="[ -d "/www/server/panel" ]" + local panelname="耗子麵板" + local panelurl="官方地址:${gh_proxy}github.com/TheTNB/panel" + + panel_app_install() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh + cd ~ + } + + panel_app_manage() { + panel-cli + } + + panel_app_uninstall() { + mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh + cd ~ + } + + install_panel + + ;; + + + 42|nexterm) + local app_id="42" + local docker_name="nexterm" + local docker_img="germannewsmaker/nexterm:latest" + local docker_port=8042 + + docker_rum() { + + ENCRYPTION_KEY=$(openssl rand -hex 32) + docker run -d \ + --name nexterm \ + -e ENCRYPTION_KEY=${ENCRYPTION_KEY} \ + -p ${docker_port}:6989 \ + -v /home/docker/nexterm:/app/data \ + --restart=always \ + germannewsmaker/nexterm:latest + + } + + local docker_describe="nexterm是一款強大的在線SSH/VNC/RDP連接工具。" + local docker_url="官網介紹:${gh_proxy}github.com/gnmyt/Nexterm" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 43|hbbs) + local app_id="43" + local docker_name="hbbs" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbs + + } + + + local docker_describe="rustdesk開源的遠程桌面(服務端),類似自己的向日葵私服。" + local docker_url="官網介紹: https://rustdesk.com/zh-cn/" + local docker_use="docker logs hbbs" + local docker_passwd="echo \"把你的IP和key記錄下,會在遠程桌面客戶端中用到。去44選項裝中繼端吧!\"" + local app_size="1" + docker_app + ;; + + 44|hbbr) + local app_id="44" + local docker_name="hbbr" + local docker_img="rustdesk/rustdesk-server" + local docker_port=0000 + + docker_rum() { + + docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart=always rustdesk/rustdesk-server hbbr + + } + + local docker_describe="rustdesk開源的遠程桌面(中繼端),類似自己的向日葵私服。" + local docker_url="官網介紹: https://rustdesk.com/zh-cn/" + local docker_use="echo \"前往官網下載遠程桌面的客戶端: https://rustdesk.com/zh-cn/\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 45|registry) + local app_id="45" + local docker_name="registry" + local docker_img="registry:2" + local docker_port=8045 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name registry \ + -v /home/docker/registry:/var/lib/registry \ + -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ + --restart=always \ + registry:2 + + } + + local docker_describe="Docker Registry 是一個用於存儲和分發 Docker 鏡像的服務。" + local docker_url="官網介紹: https://hub.docker.com/_/registry" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + ;; + + 46|ghproxy) + local app_id="46" + local docker_name="ghproxy" + local docker_img="wjqserver/ghproxy:latest" + local docker_port=8046 + + docker_rum() { + + docker run -d --name ghproxy --restart=always -p ${docker_port}:8080 -v /home/docker/ghproxy/config:/data/ghproxy/config wjqserver/ghproxy:latest + + } + + local docker_describe="使用Go實現的GHProxy,用於加速部分地區Github倉庫的拉取。" + local docker_url="官網介紹: https://github.com/WJQSERVER-STUDIO/ghproxy" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 47|prometheus|grafana) + + local app_id="47" + local app_name="普羅米修斯監控" + local app_text="Prometheus+Grafana企業級監控系統" + local app_url="官網介紹: https://prometheus.io" + local docker_name="grafana" + local docker_port="8047" + local app_size="2" + + docker_app_install() { + prometheus_install + clear + ip_address + echo "已經安裝完成" + check_docker_app_ip + echo "初始用戶名密碼均為: admin" + } + + docker_app_update() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + docker_app_install + } + + docker_app_uninstall() { + docker rm -f node-exporter prometheus grafana + docker rmi -f prom/node-exporter + docker rmi -f prom/prometheus:latest + docker rmi -f grafana/grafana:latest + + rm -rf /home/docker/monitoring + echo "應用已卸載" + } + + docker_app_plus + ;; + + 48|node-exporter) + local app_id="48" + local docker_name="node-exporter" + local docker_img="prom/node-exporter" + local docker_port=8048 + + docker_rum() { + + docker run -d \ + --name=node-exporter \ + -p ${docker_port}:9100 \ + --restart=always \ + prom/node-exporter + + + } + + local docker_describe="這是一個普羅米修斯的主機數據採集組件,請部署在被監控主機上。" + local docker_url="官網介紹: https://github.com/prometheus/node_exporter" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 49|cadvisor) + local app_id="49" + local docker_name="cadvisor" + local docker_img="gcr.io/cadvisor/cadvisor:latest" + local docker_port=8049 + + docker_rum() { + + docker run -d \ + --name=cadvisor \ + --restart=always \ + -p ${docker_port}:8080 \ + --volume=/:/rootfs:ro \ + --volume=/var/run:/var/run:rw \ + --volume=/sys:/sys:ro \ + --volume=/var/lib/docker/:/var/lib/docker:ro \ + gcr.io/cadvisor/cadvisor:latest \ + -housekeeping_interval=10s \ + -docker_only=true + + } + + local docker_describe="這是一個普羅米修斯的容器數據採集組件,請部署在被監控主機上。" + local docker_url="官網介紹: https://github.com/google/cadvisor" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 50|changedetection) + local app_id="50" + local docker_name="changedetection" + local docker_img="dgtlmoon/changedetection.io:latest" + local docker_port=8050 + + docker_rum() { + + docker run -d --restart=always -p ${docker_port}:5000 \ + -v /home/docker/datastore:/datastore \ + --name changedetection dgtlmoon/changedetection.io:latest + + } + + local docker_describe="這是一款網站變化檢測、補貨監控和通知的小工具" + local docker_url="官網介紹: https://github.com/dgtlmoon/changedetection.io" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 51|pve) + clear + send_stats "PVE開小雞" + check_disk_space 1 + curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh + ;; + + + 52|dpanel) + local app_id="52" + local docker_name="dpanel" + local docker_img="dpanel/dpanel:lite" + local docker_port=8052 + + docker_rum() { + + docker run -d --name dpanel --restart=always \ + -p ${docker_port}:8080 -e APP_NAME=dpanel \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/docker/dpanel:/dpanel \ + dpanel/dpanel:lite + + } + + local docker_describe="Docker可視化面板系統,提供完善的docker管理功能。" + local docker_url="官網介紹: https://github.com/donknap/dpanel" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 53|llama3) + local app_id="53" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大語言模型網頁框架,接入全新的llama3大語言模型" + local docker_url="官網介紹: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run llama3.2:1b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + 54|amh) + + local app_id="54" + local lujing="[ -d "/www/server/panel" ]" + local panelname="AMH面板" + local panelurl="官方地址: https://amh.sh/index.htm?amh" + + panel_app_install() { + cd ~ + wget https://dl.amh.sh/amh.sh && bash amh.sh + } + + panel_app_manage() { + panel_app_install + } + + panel_app_uninstall() { + panel_app_install + } + + install_panel + ;; + + + 55|frps) + frps_panel + ;; + + 56|frpc) + frpc_panel + ;; + + 57|deepseek) + local app_id="57" + local docker_name="ollama" + local docker_img="ghcr.io/open-webui/open-webui:ollama" + local docker_port=8053 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart=always ghcr.io/open-webui/open-webui:ollama + + } + + local docker_describe="OpenWebUI一款大語言模型網頁框架,接入全新的DeepSeek R1大語言模型" + local docker_url="官網介紹: https://github.com/open-webui/open-webui" + local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + 58|dify) + local app_id="58" + local app_name="Dify知識庫" + local app_text="是一款開源的大語言模型(LLM) 應用開發平台。自託管訓練數據用於AI生成" + local app_url="官方網站: https://docs.dify.ai/zh-hans" + local docker_name="docker-nginx-1" + local docker_port="8058" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env + sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + + docker compose up -d + + chown -R 1001:1001 /home/docker/dify/docker/volumes/app/storage + chmod -R 755 /home/docker/dify/docker/volumes/app/storage + docker compose down + docker compose up -d + + clear + echo "已經安裝完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + cd /home/docker/dify/ + git pull ${gh_proxy}github.com/langgenius/dify.git main > /dev/null 2>&1 + sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env + cd /home/docker/dify/docker/ && docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/dify/docker/ && docker compose down --rmi all + rm -rf /home/docker/dify + echo "應用已卸載" + } + + docker_app_plus + + ;; + + 59|new-api) + local app_id="59" + local app_name="NewAPI" + local app_text="新一代大模型網關與AI資產管理系統" + local app_url="官方網站: https://github.com/Calcium-Ion/new-api" + local docker_name="new-api" + local docker_port="8059" + local app_size="3" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/new-api/ && docker compose down --rmi all + cd /home/docker/new-api/ + + git pull ${gh_proxy}github.com/Calcium-Ion/new-api.git main > /dev/null 2>&1 + sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ + -e 's/container_name: redis/container_name: redis-new-api/g' \ + -e 's/container_name: mysql/container_name: mysql-new-api/g' \ + docker-compose.yml + + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + + } + + docker_app_uninstall() { + cd /home/docker/new-api/ && docker compose down --rmi all + rm -rf /home/docker/new-api + echo "應用已卸載" + } + + docker_app_plus + + ;; + + + 60|jms) + + local app_id="60" + local app_name="JumpServer開源堡壘機" + local app_text="是一個開源的特權訪問管理 (PAM) 工具,該程序佔用80端口不支持添加域名訪問了" + local app_url="官方介紹: https://github.com/jumpserver/jumpserver" + local docker_name="jms_web" + local docker_port="80" + local app_size="2" + + docker_app_install() { + curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash + clear + echo "已經安裝完成" + check_docker_app_ip + echo "初始用戶名: admin" + echo "初始密碼: ChangeMe" + } + + + docker_app_update() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh upgrade + echo "應用已更新" + } + + + docker_app_uninstall() { + cd /opt/jumpserver-installer*/ + ./jmsctl.sh uninstall + cd /opt + rm -rf jumpserver-installer*/ + rm -rf jumpserver + echo "應用已卸載" + } + + docker_app_plus + ;; + + 61|libretranslate) + local app_id="61" + local docker_name="libretranslate" + local docker_img="libretranslate/libretranslate:latest" + local docker_port=8061 + + docker_rum() { + + docker run -d \ + -p ${docker_port}:5000 \ + --name libretranslate \ + libretranslate/libretranslate \ + --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru + + } + + local docker_describe="免費開源機器翻譯 API,完全自託管,它的翻譯引擎由開源Argos Translate庫提供支持。" + local docker_url="官網介紹: https://github.com/LibreTranslate/LibreTranslate" + local docker_use="" + local docker_passwd="" + local app_size="5" + docker_app + ;; + + + + 62|ragflow) + local app_id="62" + local app_name="RAGFlow知識庫" + local app_text="基於深度文檔理解的開源 RAG(檢索增強生成)引擎" + local app_url="官方網站: https://github.com/infiniflow/ragflow" + local docker_name="ragflow-server" + local docker_port="8062" + local app_size="8" + + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } + + docker_app_update() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + cd /home/docker/ragflow/ + git pull ${gh_proxy}github.com/infiniflow/ragflow.git main > /dev/null 2>&1 + cd /home/docker/ragflow/docker/ + sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/ragflow/docker/ && docker compose down --rmi all + rm -rf /home/docker/ragflow + echo "應用已卸載" + } + + docker_app_plus + + ;; + + + 63|open-webui) + local app_id="63" + local docker_name="open-webui" + local docker_img="ghcr.io/open-webui/open-webui:main" + local docker_port=8063 + + docker_rum() { + + docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart=always ghcr.io/open-webui/open-webui:main + + } + + local docker_describe="OpenWebUI一款大語言模型網頁框架,官方精簡版本,支持各大模型API接入" + local docker_url="官網介紹: https://github.com/open-webui/open-webui" + local docker_use="" + local docker_passwd="" + local app_size="3" + docker_app + ;; + + 64|it-tools) + local app_id="64" + local docker_name="it-tools" + local docker_img="corentinth/it-tools:latest" + local docker_port=8064 + + docker_rum() { + docker run -d --name it-tools --restart=always -p ${docker_port}:80 corentinth/it-tools:latest + } + + local docker_describe="對開發人員和 IT 工作者來說非常有用的工具" + local docker_url="官網介紹: https://github.com/CorentinTh/it-tools" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 65|n8n) + local app_id="65" + local docker_name="n8n" + local docker_img="docker.n8n.io/n8nio/n8n" + local docker_port=8065 + + docker_rum() { + + add_yuming + mkdir -p /home/docker/n8n + chmod -R 777 /home/docker/n8n + + docker run -d --name n8n \ + --restart=always \ + -p ${docker_port}:5678 \ + -v /home/docker/n8n:/home/node/.n8n \ + -e N8N_HOST=${yuming} \ + -e N8N_PORT=5678 \ + -e N8N_PROTOCOL=https \ + -e WEBHOOK_URL=https://${yuming}/ \ + docker.n8n.io/n8nio/n8n + + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + + } + + local docker_describe="是一款功能強大的自動化工作流平台" + local docker_url="官網介紹: https://github.com/n8n-io/n8n" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 66|yt) + yt_menu_pro + ;; + + + 67|ddns) + local app_id="67" + local docker_name="ddns-go" + local docker_img="jeessy/ddns-go" + local docker_port=8067 + + docker_rum() { + docker run -d \ + --name ddns-go \ + --restart=always \ + -p ${docker_port}:9876 \ + -v /home/docker/ddns-go:/root \ + jeessy/ddns-go + + } + + local docker_describe="自動將你的公網 IP(IPv4/IPv6)實時更新到各大 DNS 服務商,實現動態域名解析。" + local docker_url="官網介紹: https://github.com/jeessy2/ddns-go" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + 68|allinssl) + local app_id="68" + local docker_name="allinssl" + local docker_img="allinssl/allinssl:latest" + local docker_port=8068 + + docker_rum() { + docker run -d --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest + } + + local docker_describe="開源免費的 SSL 證書自動化管理平台" + local docker_url="官網介紹: https://allinssl.com" + local docker_use="echo \"安全入口: /allinssl\"" + local docker_passwd="echo \"用戶名: allinssl 密碼: allinssldocker\"" + local app_size="1" + docker_app + ;; + + + 69|sftpgo) + local app_id="69" + local docker_name="sftpgo" + local docker_img="drakkan/sftpgo:latest" + local docker_port=8069 + + docker_rum() { + + mkdir -p /home/docker/sftpgo/data + mkdir -p /home/docker/sftpgo/config + chown -R 1000:1000 /home/docker/sftpgo + + docker run -d \ + --name sftpgo \ + --restart=always \ + -p ${docker_port}:8080 \ + -p 22022:2022 \ + --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ + --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ + drakkan/sftpgo:latest + + } + + local docker_describe="開源免費隨時隨地SFTP FTP WebDAV 文件傳輸工具" + local docker_url="官網介紹: https://sftpgo.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 70|astrbot) + local app_id="70" + local docker_name="astrbot" + local docker_img="soulter/astrbot:latest" + local docker_port=8070 + + docker_rum() { + + mkdir -p /home/docker/astrbot/data + + docker run -d \ + -p ${docker_port}:6185 \ + -p 6195:6195 \ + -p 6196:6196 \ + -p 6199:6199 \ + -p 11451:11451 \ + -v /home/docker/astrbot/data:/AstrBot/data \ + --restart=always \ + --name astrbot \ + soulter/astrbot:latest + + } + + local docker_describe="開源AI聊天機器人框架,支持微信,QQ,TG接入AI大模型" + local docker_url="官網介紹: https://astrbot.app/" + local docker_use="echo \"用戶名: astrbot 密碼: astrbot\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 71|navidrome) + local app_id="71" + local docker_name="navidrome" + local docker_img="deluan/navidrome:latest" + local docker_port=8071 + + docker_rum() { + + docker run -d \ + --name navidrome \ + --restart=always \ + --user $(id -u):$(id -g) \ + -v /home/docker/navidrome/music:/music \ + -v /home/docker/navidrome/data:/data \ + -p ${docker_port}:4533 \ + -e ND_LOGLEVEL=info \ + deluan/navidrome:latest + + } + + local docker_describe="是一個輕量、高性能的音樂流媒體服務器" + local docker_url="官網介紹: https://www.navidrome.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; + + + 72|bitwarden) + + local app_id="72" + local docker_name="bitwarden" + local docker_img="vaultwarden/server" + local docker_port=8072 + + docker_rum() { + + docker run -d \ + --name bitwarden \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/bitwarden/data:/data \ + vaultwarden/server + + } + + local docker_describe="一個你可以控制數據的密碼管理器" + local docker_url="官網介紹: https://bitwarden.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + + 73|libretv) + + local app_id="73" + local docker_name="libretv" + local docker_img="bestzwei/libretv:latest" + local docker_port=8073 + + docker_rum() { + + read -e -p "設置LibreTV的登錄密碼:" app_passwd + + docker run -d \ + --name libretv \ + --restart=always \ + -p ${docker_port}:8080 \ + -e PASSWORD=${app_passwd} \ + bestzwei/libretv:latest + + } + + local docker_describe="免費在線視頻搜索與觀看平台" + local docker_url="官網介紹: https://github.com/LibreSpark/LibreTV" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + ;; + + + + 74|moontv) + + local app_id="74" + + local app_name="moontv私有影視" + local app_text="免費在線視頻搜索與觀看平台" + local app_url="視頻介紹: https://github.com/MoonTechLab/LunaTV" + local docker_name="moontv-core" + local docker_port="8074" + local app_size="2" + + docker_app_install() { + read -e -p "設置登錄用戶名:" admin + read -e -p "設置登錄用戶密碼:" admin_password + read -e -p "輸入授權碼:" shouquanma + + + mkdir -p /home/docker/moontv + mkdir -p /home/docker/moontv/config + mkdir -p /home/docker/moontv/data + cd /home/docker/moontv + + curl -o /home/docker/moontv/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/moontv-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin_password|${admin_password}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|admin|${admin}|g" /home/docker/moontv/docker-compose.yml + sed -i "s|shouquanma|${shouquanma}|g" /home/docker/moontv/docker-compose.yml + cd /home/docker/moontv/ + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } + + + docker_app_update() { + cd /home/docker/moontv/ && docker compose down --rmi all + cd /home/docker/moontv/ && docker compose up -d + } + + + docker_app_uninstall() { + cd /home/docker/moontv/ && docker compose down --rmi all + rm -rf /home/docker/moontv + echo "應用已卸載" + } + + docker_app_plus + + ;; + + + 75|melody) + + local app_id="75" + local docker_name="melody" + local docker_img="foamzou/melody:latest" + local docker_port=8075 + + docker_rum() { + + docker run -d \ + --name melody \ + --restart=always \ + -p ${docker_port}:5566 \ + -v /home/docker/melody/.profile:/app/backend/.profile \ + foamzou/melody:latest + + + } + + local docker_describe="你的音樂精靈,旨在幫助你更好地管理音樂。" + local docker_url="官網介紹: https://github.com/foamzou/melody" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + + + ;; + + + 76|dosgame) + + local app_id="76" + local docker_name="dosgame" + local docker_img="oldiy/dosgame-web-docker:latest" + local docker_port=8076 + + docker_rum() { + docker run -d \ + --name dosgame \ + --restart=always \ + -p ${docker_port}:262 \ + oldiy/dosgame-web-docker:latest + + } + + local docker_describe="是一個中文DOS遊戲合集網站" + local docker_url="官網介紹: https://github.com/rwv/chinese-dos-games" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app + + + ;; + + 77|xunlei) + + local app_id="77" + local docker_name="xunlei" + local docker_img="cnk3x/xunlei" + local docker_port=8077 + + docker_rum() { + + read -e -p "設置登錄用戶名:" app_use + read -e -p "設置登錄密碼:" app_passwd + + docker run -d \ + --name xunlei \ + --restart=always \ + --privileged \ + -e XL_DASHBOARD_USERNAME=${app_use} \ + -e XL_DASHBOARD_PASSWORD=${app_passwd} \ + -v /home/docker/xunlei/data:/xunlei/data \ + -v /home/docker/xunlei/downloads:/xunlei/downloads \ + -p ${docker_port}:2345 \ + cnk3x/xunlei + + } - docker_rum() { + local docker_describe="迅雷你的離線高速BT磁力下載工具" + local docker_url="官網介紹: https://github.com/cnk3x/xunlei" + local docker_use="echo \"手機登錄迅雷,再輸入邀請碼,邀請碼: 迅雷牛通\"" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d --name=emby --restart=always \ - -v /home/docker/emby/config:/config \ - -v /home/docker/emby/share1:/mnt/share1 \ - -v /home/docker/emby/share2:/mnt/share2 \ - -v /mnt/notify:/mnt/notify \ - -p ${docker_port}:8096 \ - -e UID=1000 -e GID=100 -e GIDLIST=100 \ - linuxserver/emby:latest + ;; - } - local docker_describe="emby是一个主从式架构的媒体服务器软件,可以用来整理服务器上的视频和音频,并将音频和视频流式传输到客户端设备" - local docker_url="官网介绍: https://emby.media/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 78|PandaWiki) - 16) - local docker_name="looking-glass" - local docker_img="wikihostinc/looking-glass-server" - local docker_port=89 + local app_id="78" + local app_name="PandaWiki" + local app_text="PandaWiki是一款AI大模型驅動的開源智能文檔管理系統,強烈建議不要自定義端口部署。" + local app_url="官方介紹: https://github.com/chaitin/PandaWiki" + local docker_name="panda-wiki-nginx" + local docker_port="2443" + local app_size="2" + docker_app_install() { + bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" + } - docker_rum() { + docker_app_update() { + docker_app_install + } - docker run -d --name looking-glass --restart always -p ${docker_port}:80 wikihostinc/looking-glass-server - } + docker_app_uninstall() { + docker_app_install + } - local docker_describe="Speedtest测速面板是一个VPS网速测试工具,多项测试功能,还可以实时监控VPS进出站流量" - local docker_url="官网介绍: ${gh_proxy}github.com/wikihost-opensource/als" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_plus + ;; - ;; - 17) - local docker_name="adguardhome" - local docker_img="adguard/adguardhome" - local docker_port=3000 - docker_rum() { + 79|beszel) - docker run -d \ - --name adguardhome \ - -v /home/docker/adguardhome/work:/opt/adguardhome/work \ - -v /home/docker/adguardhome/conf:/opt/adguardhome/conf \ - -p 53:53/tcp \ - -p 53:53/udp \ - -p ${docker_port}:3000/tcp \ - --restart always \ - adguard/adguardhome + local app_id="79" + local docker_name="beszel" + local docker_img="henrygd/beszel" + local docker_port=8079 + docker_rum() { - } + mkdir -p /home/docker/beszel && \ + docker run -d \ + --name beszel \ + --restart=always \ + -v /home/docker/beszel:/beszel_data \ + -p ${docker_port}:8090 \ + henrygd/beszel + } - local docker_describe="AdGuardHome是一款全网广告拦截与反跟踪软件,未来将不止是一个DNS服务器。" - local docker_url="官网介绍: https://hub.docker.com/r/adguard/adguardhome" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + local docker_describe="Beszel輕量易用的服務器監控" + local docker_url="官網介紹: https://beszel.dev/zh/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - ;; + ;; - 18) + 80|linkwarden) - local docker_name="onlyoffice" - local docker_img="onlyoffice/documentserver" - local docker_port=8082 + local app_id="80" + local app_name="linkwarden書籤管理" + local app_text="一個開源的自託管書籤管理平台,支持標籤、搜索和團隊協作。" + local app_url="官方網站: https://linkwarden.app/" + local docker_name="linkwarden-linkwarden-1" + local docker_port="8080" + local app_size="3" - docker_rum() { + docker_app_install() { + install git openssl + mkdir -p /home/docker/linkwarden && cd /home/docker/linkwarden - docker run -d -p ${docker_port}:80 \ - --restart=always \ - --name onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice \ - -v /home/docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data \ - onlyoffice/documentserver + # 下載官方 docker-compose 和 env 文件 + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env" + # 生成隨機密鑰與密碼 + local ADMIN_EMAIL="admin@example.com" + local ADMIN_PASSWORD=$(openssl rand -hex 8) - } + sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://localhost:${docker_port}/api/v1/auth|g" .env + sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=$(openssl rand -hex 32)|g" .env + sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$(openssl rand -hex 16)|g" .env + sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$(openssl rand -hex 32)|g" .env - local docker_describe="onlyoffice是一款开源的在线office工具,太强大了!" - local docker_url="官网介绍: https://www.onlyoffice.com/" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + # 追加管理員賬號信息 + echo "ADMIN_EMAIL=${ADMIN_EMAIL}" >> .env + echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env - ;; + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml - 19) - send_stats "搭建雷池" + # 啟動容器 + docker compose up -d - local docker_name=safeline-mgt - local docker_port=9443 - while true; do - check_docker_app - clear - echo -e "雷池服務$check_docker" - echo "雷池是長亭科技開發的WAF站點防火牆程序面板,可以反代站點進行自動化防禦" - echo "視頻介紹: https://www.bilibili.com/video/BV1mZ421T74c?t=0.1" - if docker inspect "$docker_name" &>/dev/null; then - check_docker_app_ip - fi - echo "" + clear + echo "已經安裝完成" + check_docker_app_ip + + } + + docker_app_update() { + cd /home/docker/linkwarden && docker compose down --rmi all + curl -O ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/docker-compose.yml + curl -L ${gh_proxy}raw.githubusercontent.com/linkwarden/linkwarden/refs/heads/main/.env.sample -o ".env.new" + + # 保留原本的變量 + source .env + mv .env.new .env + echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env + echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET" >> .env + echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> .env + echo "MEILI_MASTER_KEY=$MEILI_MASTER_KEY" >> .env + echo "ADMIN_EMAIL=$ADMIN_EMAIL" >> .env + echo "ADMIN_PASSWORD=$ADMIN_PASSWORD" >> .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/linkwarden/docker-compose.yml + + docker compose up -d + } + + docker_app_uninstall() { + cd /home/docker/linkwarden && docker compose down --rmi all + rm -rf /home/docker/linkwarden + echo "應用已卸載" + } + + docker_app_plus - echo "------------------------" - echo "1. 安裝 2. 更新 3. 重置密碼 4. 卸載" - echo "------------------------" - echo "0. 返回上一級選單" - echo "------------------------" - read -e -p "輸入你的選擇:" choice + ;; - case $choice in - 1) - install_docker - check_disk_space 5 - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" - clear - echo "雷池WAF面板已經安裝完成" - check_docker_app_ip - docker exec safeline-mgt resetadmin - ;; - 2) - bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)" - docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}') - echo "" - clear - echo "雷池WAF面板已經更新完成" - check_docker_app_ip - ;; - 3) - docker exec safeline-mgt resetadmin - ;; - 4) - cd /data/safeline - docker compose down --rmi all - echo "如果你是默認安裝目錄那現在項目已經卸載。如果你是自定義安裝目錄你需要到安裝目錄下自行執行:" - echo "docker compose down && docker compose down --rmi all" - ;; - *) - break - ;; + 81|jitsi) + local app_id="81" + local app_name="JitsiMeet視頻會議" + local app_text="一個開源的安全視頻會議解決方案,支持多人在線會議、屏幕共享與加密通信。" + local app_url="官方網站: https://jitsi.org/" + local docker_name="jitsi" + local docker_port="8081" + local app_size="3" - esac - break_end - done + docker_app_install() { - ;; + add_yuming + mkdir -p /home/docker/jitsi && cd /home/docker/jitsi + wget $(wget -q -O - https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep zip | cut -d\" -f4) + unzip "$(ls -t | head -n 1)" + cd "$(ls -dt */ | head -n 1)" + cp env.example .env + ./gen-passwords.sh + mkdir -p ~/.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri} + sed -i "s|^HTTP_PORT=.*|HTTP_PORT=${docker_port}|" .env + sed -i "s|^#PUBLIC_URL=https://meet.example.com:\${HTTPS_PORT}|PUBLIC_URL=https://$yuming:443|" .env + docker compose up -d - 20) - local docker_name="portainer" - local docker_img="portainer/portainer" - local docker_port=9050 + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker_rum() { + } - docker run -d \ - --name portainer \ - -p ${docker_port}:9000 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/portainer:/data \ - --restart always \ - portainer/portainer + docker_app_update() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + docker compose up -d - } + } + docker_app_uninstall() { + cd /home/docker/jitsi + cd "$(ls -dt */ | head -n 1)" + docker compose down --rmi all + rm -rf /home/docker/jitsi + echo "應用已卸載" + } - local docker_describe="portainer是一个轻量级的docker容器管理面板" - local docker_url="官网介绍: https://www.portainer.io/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_plus - ;; + ;; - 21) - local docker_name="vscode-web" - local docker_img="codercom/code-server" - local docker_port=8180 - docker_rum() { + 82|gpt-load) - docker run -d -p ${docker_port}:8080 -v /home/docker/vscode-web:/home/coder/.local/share/code-server --name vscode-web --restart always codercom/code-server + local app_id="82" + local docker_name="gpt-load" + local docker_img="tbphp/gpt-load:latest" + local docker_port=8082 - } + docker_rum() { + read -e -p "設定${docker_name}的登錄密鑰(sk-開頭字母和數字組合)如: sk-159kejilionyyds163:" app_passwd - local docker_describe="VScode是一款强大的在线代码编写工具" - local docker_url="官网介绍: ${gh_proxy}github.com/coder/code-server" - local docker_use="sleep 3" - local docker_passwd="docker exec vscode-web cat /home/coder/.config/code-server/config.yaml" - local app_size="1" - docker_app - ;; - 22) - local docker_name="uptime-kuma" - local docker_img="louislam/uptime-kuma:latest" - local docker_port=3003 + mkdir -p /home/docker/gpt-load && \ + docker run -d --name gpt-load \ + -p ${docker_port}:3001 \ + -e AUTH_KEY=${app_passwd} \ + -v "/home/docker/gpt-load/data":/app/data \ + tbphp/gpt-load:latest + } - docker_rum() { + local docker_describe="高性能AI接口透明代理服務" + local docker_url="官網介紹: https://www.gpt-load.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run -d \ - --name=uptime-kuma \ - -p ${docker_port}:3001 \ - -v /home/docker/uptime-kuma/uptime-kuma-data:/app/data \ - --restart=always \ - louislam/uptime-kuma:latest + ;; - } - local docker_describe="Uptime Kuma 易于使用的自托管监控工具" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/uptime-kuma" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 83|komari) - 23) - local docker_name="memos" - local docker_img="ghcr.io/usememos/memos:latest" - local docker_port=5230 + local app_id="83" + local docker_name="komari" + local docker_img="ghcr.io/komari-monitor/komari:latest" + local docker_port=8083 - docker_rum() { + docker_rum() { - docker run -d --name memos -p ${docker_port}:5230 -v /home/docker/memos:/var/opt/memos --restart always ghcr.io/usememos/memos:latest + mkdir -p /home/docker/komari && \ + docker run -d \ + --name komari \ + -p ${docker_port}:25774 \ + -v /home/docker/komari:/app/data \ + -e ADMIN_USERNAME=admin \ + -e ADMIN_PASSWORD=1212156 \ + -e TZ=Asia/Shanghai \ + --restart=always \ + ghcr.io/komari-monitor/komari:latest - } + } - local docker_describe="Memos是一款轻量级、自托管的备忘录中心" - local docker_url="官网介绍: ${gh_proxy}github.com/usememos/memos" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="輕量級的自託管服務器監控工具" + local docker_url="官網介紹: https://github.com/komari-monitor/komari/tree/main" + local docker_use="echo \"默認賬號: admin 默認密碼: 1212156\"" + local docker_passwd="" + local app_size="1" + docker_app - 24) - local docker_name="webtop" - local docker_img="lscr.io/linuxserver/webtop:latest" - local docker_port=3083 + ;; - docker_rum() { - docker run -d \ - --name=webtop \ - --security-opt seccomp=unconfined \ - -e PUID=1000 \ - -e PGID=1000 \ - -e TZ=Etc/UTC \ - -e SUBFOLDER=/ \ - -e TITLE=Webtop \ - -e CUSTOM_USER=webtop-abc \ - -e PASSWORD=webtopABC123 \ - -e LC_ALL=zh_CN.UTF-8 \ - -e DOCKER_MODS=linuxserver/mods:universal-package-install \ - -e INSTALL_PACKAGES=font-noto-cjk \ - -p ${docker_port}:3000 \ - -v /home/docker/webtop/data:/config \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --shm-size="1gb" \ - --restart unless-stopped \ - lscr.io/linuxserver/webtop:latest + 84|wallos) + local app_id="84" + local docker_name="wallos" + local docker_img="bellamy/wallos:latest" + local docker_port=8084 - } + docker_rum() { + mkdir -p /home/docker/wallos && \ + docker run -d --name wallos \ + -v /home/docker/wallos/db:/var/www/html/db \ + -v /home/docker/wallos/logos:/var/www/html/images/uploads/logos \ + -e TZ=UTC \ + -p ${docker_port}:80 \ + --restart=always \ + bellamy/wallos:latest - local docker_describe="webtop基于Alpine的中文版容器。若IP无法访问,请添加域名访问。" - local docker_url="官网介绍: https://docs.linuxserver.io/images/docker-webtop/" - local docker_use="echo \"用户名: webtop-abc\"" - local docker_passwd="echo \"密码: webtopABC123\"" - local app_size="2" - docker_app - ;; + } - 25) - local docker_name="nextcloud" - local docker_img="nextcloud:latest" - local docker_port=8989 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) + local docker_describe="開源個人訂閱追踪器,可用於財務管理" + local docker_url="官網介紹: https://github.com/ellite/Wallos" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d --name nextcloud --restart=always -p ${docker_port}:80 -v /home/docker/nextcloud:/var/www/html -e NEXTCLOUD_ADMIN_USER=nextcloud -e NEXTCLOUD_ADMIN_PASSWORD=$rootpasswd nextcloud + 85|immich) - } + local app_id="85" + local app_name="immich圖片視頻管理器" + local app_text="高性能自託管照片和視頻管理解決方案。" + local app_url="官網介紹: https://github.com/immich-app/immich" + local docker_name="immich_server" + local docker_port="8085" + local app_size="3" - local docker_describe="Nextcloud拥有超过 400,000 个部署,是您可以下载的最受欢迎的本地内容协作平台" - local docker_url="官网介绍: https://nextcloud.com/" - local docker_use="echo \"账号: nextcloud 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="3" - docker_app - ;; + docker_app_install() { + install git openssl wget + mkdir -p /home/docker/${docker_name} && cd /home/docker/${docker_name} - 26) - local docker_name="qd" - local docker_img="qdtoday/qd:latest" - local docker_port=8923 + wget -O docker-compose.yml ${gh_proxy}github.com/immich-app/immich/releases/latest/download/docker-compose.yml + wget -O .env ${gh_proxy}github.com/immich-app/immich/releases/latest/download/example.env + sed -i "s/2283:2283/${docker_port}:2283/g" /home/docker/${docker_name}/docker-compose.yml - docker_rum() { + docker compose up -d - docker run -d --name qd -p ${docker_port}:80 -v /home/docker/qd/config:/usr/src/app/config qdtoday/qd + clear + echo "已經安裝完成" + check_docker_app_ip - } + } - local docker_describe="QD-Today是一个HTTP请求定时任务自动执行框架" - local docker_url="官网介绍: https://qd-today.github.io/qd/zh_CN/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 27) - local docker_name="dockge" - local docker_img="louislam/dockge:latest" - local docker_port=5003 + docker_app_update() { + cd /home/docker/${docker_name} && docker compose down --rmi all + docker_app_install + } - docker_rum() { + docker_app_uninstall() { + cd /home/docker/${docker_name} && docker compose down --rmi all + rm -rf /home/docker/${docker_name} + echo "應用已卸載" + } - docker run -d --name dockge --restart unless-stopped -p ${docker_port}:5001 -v /var/run/docker.sock:/var/run/docker.sock -v /home/docker/dockge/data:/app/data -v /home/docker/dockge/stacks:/home/docker/dockge/stacks -e DOCKGE_STACKS_DIR=/home/docker/dockge/stacks louislam/dockge + docker_app_plus - } - local docker_describe="dockge是一个可视化的docker-compose容器管理面板" - local docker_url="官网介绍: ${gh_proxy}github.com/louislam/dockge" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 28) - local docker_name="speedtest" - local docker_img="ghcr.io/librespeed/speedtest" - local docker_port=8028 - docker_rum() { + 86|jellyfin) - docker run -d -p ${docker_port}:8080 --name speedtest --restart always ghcr.io/librespeed/speedtest + local app_id="86" + local docker_name="jellyfin" + local docker_img="jellyfin/jellyfin" + local docker_port=8086 - } + docker_rum() { - local docker_describe="librespeed是用Javascript实现的轻量级速度测试工具,即开即用" - local docker_url="官网介绍: ${gh_proxy}github.com/librespeed/speedtest" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/jellyfin/media + chmod -R 777 /home/docker/jellyfin - 29) - local docker_name="searxng" - local docker_img="searxng/searxng" - local docker_port=8029 + docker run -d \ + --name jellyfin \ + --user root \ + --volume /home/docker/jellyfin/config:/config \ + --volume /home/docker/jellyfin/cache:/cache \ + --mount type=bind,source=/home/docker/jellyfin/media,target=/media \ + -p ${docker_port}:8096 \ + -p 7359:7359/udp \ + --restart=always \ + jellyfin/jellyfin - docker_rum() { - docker run -d \ - --name searxng \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -v "/home/docker/searxng:/etc/searxng" \ - searxng/searxng + } - } + local docker_describe="是一款開源媒體服務器軟件" + local docker_url="官網介紹: https://jellyfin.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="searxng是一个私有且隐私的搜索引擎站点" - local docker_url="官网介绍: https://hub.docker.com/r/alandoyle/searxng" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 30) - local docker_name="photoprism" - local docker_img="photoprism/photoprism:latest" - local docker_port=2342 - local rootpasswd=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c16) - docker_rum() { + 87|synctv) - docker run -d \ - --name photoprism \ - --restart always \ - --security-opt seccomp=unconfined \ - --security-opt apparmor=unconfined \ - -p ${docker_port}:2342 \ - -e PHOTOPRISM_UPLOAD_NSFW="true" \ - -e PHOTOPRISM_ADMIN_PASSWORD="$rootpasswd" \ - -v /home/docker/photoprism/storage:/photoprism/storage \ - -v /home/docker/photoprism/Pictures:/photoprism/originals \ - photoprism/photoprism + local app_id="87" + local docker_name="synctv" + local docker_img="synctvorg/synctv" + local docker_port=8087 - } + docker_rum() { + docker run -d \ + --name synctv \ + -v /home/docker/synctv:/root/.synctv \ + -p ${docker_port}:8080 \ + --restart=always \ + synctvorg/synctv - local docker_describe="photoprism非常强大的私有相册系统" - local docker_url="官网介绍: https://www.photoprism.app/" - local docker_use="echo \"账号: admin 密码: $rootpasswd\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="遠程一起觀看電影和直播的程序。它提供了同步觀影、直播、聊天等功能" + local docker_url="官網介紹: https://github.com/synctv-org/synctv" + local docker_use="echo \"初始賬號和密碼: root 登陸後請及時修改登錄密碼\"" + local docker_passwd="" + local app_size="1" + docker_app - 31) - local docker_name="s-pdf" - local docker_img="frooodle/s-pdf:latest" - local docker_port=8020 - - docker_rum() { - - docker run -d \ - --name s-pdf \ - --restart=always \ - -p ${docker_port}:8080 \ - -v /home/docker/s-pdf/trainingData:/usr/share/tesseract-ocr/5/tessdata \ - -v /home/docker/s-pdf/extraConfigs:/configs \ - -v /home/docker/s-pdf/logs:/logs \ - -e DOCKER_ENABLE_SECURITY=false \ - frooodle/s-pdf:latest - } - - local docker_describe="这是一个强大的本地托管基于 Web 的 PDF 操作工具,使用 docker,允许您对 PDF 文件执行各种操作,例如拆分合并、转换、重新组织、添加图像、旋转、压缩等。" - local docker_url="官网介绍: ${gh_proxy}github.com/Stirling-Tools/Stirling-PDF" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 32) - local docker_name="drawio" - local docker_img="jgraph/drawio" - local docker_port=7080 - docker_rum() { + 88|owncast) - docker run -d --restart=always --name drawio -p ${docker_port}:8080 -v /home/docker/drawio:/var/lib/drawio jgraph/drawio + local app_id="88" + local docker_name="owncast" + local docker_img="owncast/owncast:latest" + local docker_port=8088 - } + docker_rum() { + docker run -d \ + --name owncast \ + -p ${docker_port}:8080 \ + -p 1935:1935 \ + -v /home/docker/owncast/data:/app/data \ + --restart=always \ + owncast/owncast:latest - local docker_describe="这是一个强大图表绘制软件。思维导图,拓扑图,流程图,都能画" - local docker_url="官网介绍: https://www.drawio.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 33) - local docker_name="sun-panel" - local docker_img="hslr/sun-panel" - local docker_port=3009 + } - docker_rum() { + local docker_describe="開源、免費的自建直播平台" + local docker_url="官網介紹: https://owncast.online" + local docker_use="echo \"訪問地址後面帶 /admin 訪問管理員頁面\"" + local docker_passwd="echo \"初始賬號: admin 初始密碼: abc123 登陸後請及時修改登錄密碼\"" + local app_size="1" + docker_app - docker run -d --restart=always -p ${docker_port}:3002 \ - -v /home/docker/sun-panel/conf:/app/conf \ - -v /home/docker/sun-panel/uploads:/app/uploads \ - -v /home/docker/sun-panel/database:/app/database \ - --name sun-panel \ - hslr/sun-panel + ;; - } - local docker_describe="Sun-Panel服务器、NAS导航面板、Homepage、浏览器首页" - local docker_url="官网介绍: https://doc.sun-panel.top/zh_cn/" - local docker_use="echo \"账号: admin@sun.cc 密码: 12345678\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 34) - local docker_name="pingvin-share" - local docker_img="stonith404/pingvin-share" - local docker_port=3060 + 89|file-code-box) - docker_rum() { + local app_id="89" + local docker_name="file-code-box" + local docker_img="lanol/filecodebox:latest" + local docker_port=8089 - docker run -d \ - --name pingvin-share \ - --restart always \ - -p ${docker_port}:3000 \ - -v /home/docker/pingvin-share/data:/opt/app/backend/data \ - stonith404/pingvin-share - } + docker_rum() { - local docker_describe="Pingvin Share 是一个可自建的文件分享平台,是 WeTransfer 的一个替代品" - local docker_url="官网介绍: ${gh_proxy}github.com/stonith404/pingvin-share" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker run -d \ + --name file-code-box \ + -p ${docker_port}:12345 \ + -v /home/docker/file-code-box/data:/app/data \ + --restart=always \ + lanol/filecodebox:latest + } - 35) - local docker_name="moments" - local docker_img="kingwrcy/moments:latest" - local docker_port=8035 + local docker_describe="匿名口令分享文本和文件,像拿快遞一樣取文件" + local docker_url="官網介紹: https://github.com/vastsa/FileCodeBox" + local docker_use="echo \"訪問地址後面帶 /#/admin 訪問管理員頁面\"" + local docker_passwd="echo \"管理員密碼: FileCodeBox2023\"" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d --restart unless-stopped \ - -p ${docker_port}:3000 \ - -v /home/docker/moments/data:/app/data \ - -v /etc/localtime:/etc/localtime:ro \ - -v /etc/timezone:/etc/timezone:ro \ - --name moments \ - kingwrcy/moments:latest - } - local docker_describe="极简朋友圈,高仿微信朋友圈,记录你的美好生活" - local docker_url="官網介紹:${gh_proxy}github.com/kingwrcy/moments?tab=readme-ov-file" - local docker_use="echo \"账号: admin 密码: a123456\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 90|matrix) + local app_id="90" + local docker_name="matrix" + local docker_img="matrixdotorg/synapse:latest" + local docker_port=8090 - 36) - local docker_name="lobe-chat" - local docker_img="lobehub/lobe-chat:latest" - local docker_port=8036 + docker_rum() { - docker_rum() { + add_yuming - docker run -d -p ${docker_port}:3210 \ - --name lobe-chat \ - --restart=always \ - lobehub/lobe-chat - } + if [ ! -d /home/docker/matrix/data ]; then + docker run --rm \ + -v /home/docker/matrix/data:/data \ + -e SYNAPSE_SERVER_NAME=${yuming} \ + -e SYNAPSE_REPORT_STATS=yes \ + --name matrix \ + matrixdotorg/synapse:latest generate + fi - local docker_describe="LobeChat聚合市面上主流的AI大模型,ChatGPT/Claude/Gemini/Groq/Ollama" - local docker_url="官网介绍: ${gh_proxy}github.com/lobehub/lobe-chat" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + docker run -d \ + --name matrix \ + -v /home/docker/matrix/data:/data \ + -p ${docker_port}:8008 \ + --restart=always \ + matrixdotorg/synapse:latest - 37) - local docker_name="myip" - local docker_img="jason5ng32/myip:latest" - local docker_port=8037 + echo "創建初始用戶或管理員。請設置以下內容用戶名和密碼以及是否為管理員。" + docker exec -it matrix register_new_matrix_user \ + http://localhost:8008 \ + -c /data/homeserver.yaml - docker_rum() { + sed -i '/^enable_registration:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration: true' /home/docker/matrix/data/homeserver.yaml + sed -i '/^enable_registration_without_verification:/d' /home/docker/matrix/data/homeserver.yaml + sed -i '/^# vim:ft=yaml/i enable_registration_without_verification: true' /home/docker/matrix/data/homeserver.yaml - docker run -d -p ${docker_port}:18966 --name myip jason5ng32/myip:latest + docker restart matrix - } + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" + } - local docker_describe="是一个多功能IP工具箱,可以查看自己IP信息及连通性,用网页面板呈现" - local docker_url="官网介绍: ${gh_proxy}github.com/jason5ng32/MyIP/blob/main/README_ZH.md" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local docker_describe="Matrix是一個去中心化的聊天協議" + local docker_url="官網介紹: https://matrix.org/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 38) - send_stats "小雅全家桶" - clear - install_docker - check_disk_space 1 - bash -c "$(curl --insecure -fsSL https://ddsrem.com/xiaoya_install.sh)" - ;; + ;; - 39) - if [ ! -d /home/docker/bililive-go/ ]; then - mkdir -p /home/docker/bililive-go/ > /dev/null 2>&1 - wget -O /home/docker/bililive-go/config.yml ${gh_proxy}raw.githubusercontent.com/hr3lxphr6j/bililive-go/master/config.yml > /dev/null 2>&1 - fi - local docker_name="bililive-go" - local docker_img="chigusa/bililive-go" - local docker_port=8039 + 91|gitea) - docker_rum() { + local app_id="91" - docker run --restart=always --name bililive-go -v /home/docker/bililive-go/config.yml:/etc/bililive-go/config.yml -v /home/docker/bililive-go/Videos:/srv/bililive -p ${docker_port}:8080 -d chigusa/bililive-go + local app_name="gitea私有代碼倉庫" + local app_text="免費新一代的代碼託管平台,提供接近 GitHub 的使用體驗。" + local app_url="視頻介紹: https://github.com/go-gitea/gitea" + local docker_name="gitea" + local docker_port="8091" + local app_size="2" - } + docker_app_install() { - local docker_describe="Bililive-go是一个支持多种直播平台的直播录制工具" - local docker_url="官网介绍: ${gh_proxy}github.com/hr3lxphr6j/bililive-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/gitea + mkdir -p /home/docker/gitea/gitea + mkdir -p /home/docker/gitea/data + mkdir -p /home/docker/gitea/postgres + cd /home/docker/gitea - 40) - local docker_name="webssh" - local docker_img="jrohy/webssh" - local docker_port=8040 - docker_rum() { - docker run -d -p ${docker_port}:5032 --restart always --name webssh -e TZ=Asia/Shanghai jrohy/webssh - } + curl -o /home/docker/gitea/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/gitea-docker-compose.yml + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/gitea/docker-compose.yml + cd /home/docker/gitea/ + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - local docker_describe="简易在线ssh连接工具和sftp工具" - local docker_url="官网介绍: ${gh_proxy}github.com/Jrohy/webssh" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 41) + docker_app_update() { + cd /home/docker/gitea/ && docker compose down --rmi all + cd /home/docker/gitea/ && docker compose up -d + } - local lujing="[ -d "/www/server/panel" ]" - local panelname="耗子面板" - local panelurl="官方地址: ${gh_proxy}github.com/TheTNB/panel" - panel_app_install() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o install.sh https://dl.cdn.haozi.net/panel/install.sh && bash install.sh - cd ~ - } + docker_app_uninstall() { + cd /home/docker/gitea/ && docker compose down --rmi all + rm -rf /home/docker/gitea + echo "應用已卸載" + } - panel_app_manage() { - panel-cli - } + docker_app_plus - panel_app_uninstall() { - mkdir -p ~/haozi && cd ~/haozi && curl -fsLm 10 -o uninstall.sh https://dl.cdn.haozi.net/panel/uninstall.sh && bash uninstall.sh - cd ~ - } + ;; - install_panel - ;; - 42) - local docker_name="nexterm" - local docker_img="germannewsmaker/nexterm:latest" - local docker_port=8042 + 92|filebrowser) - docker_rum() { + local app_id="92" + local docker_name="filebrowser" + local docker_img="hurlenko/filebrowser" + local docker_port=8092 - docker run -d \ - --name nexterm \ - -p ${docker_port}:6989 \ - -v /home/docker/nexterm:/app/data \ - --restart unless-stopped \ - germannewsmaker/nexterm:latest + docker_rum() { - } + docker run -d \ + --name filebrowser \ + --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/filebrowser/data:/data \ + -v /home/docker/filebrowser/config:/config \ + -e FB_BASEURL=/filebrowser \ + hurlenko/filebrowser - local docker_describe="nexterm是一款强大的在线SSH/VNC/RDP连接工具。" - local docker_url="官网介绍: ${gh_proxy}github.com/gnmyt/Nexterm" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } - 43) - local docker_name="hbbs" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + local docker_describe="是一個基於Web的文件管理器" + local docker_url="官網介紹: https://filebrowser.org/" + local docker_use="docker logs filebrowser" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run --name hbbs -v /home/docker/hbbs/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbs + 93|dufs) - } + local app_id="93" + local docker_name="dufs" + local docker_img="sigoden/dufs" + local docker_port=8093 + docker_rum() { - local docker_describe="rustdesk开源的远程桌面(服务端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="docker logs hbbs" - local docker_passwd="echo \"把你的IP和key记录下,会在远程桌面客户端中用到。去44选项装中继端吧!\"" - local app_size="1" - docker_app - ;; + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}:/data \ + -p ${docker_port}:5000 \ + ${docker_img} /data -A - 44) - local docker_name="hbbr" - local docker_img="rustdesk/rustdesk-server" - local docker_port=0000 + } - docker_rum() { + local docker_describe="極簡靜態文件服務器,支持上傳下載" + local docker_url="官網介紹: https://github.com/sigoden/dufs" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker run --name hbbr -v /home/docker/hbbr/data:/root -td --net=host --restart unless-stopped rustdesk/rustdesk-server hbbr + ;; - } + 94|gopeed) - local docker_describe="rustdesk开源的远程桌面(中继端),类似自己的向日葵私服。" - local docker_url="官网介绍: https://rustdesk.com/zh-cn/" - local docker_use="echo \"前往官网下载远程桌面的客户端: https://rustdesk.com/zh-cn/\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="94" + local docker_name="gopeed" + local docker_img="liwei2633/gopeed" + local docker_port=8094 - 45) - local docker_name="registry" - local docker_img="registry:2" - local docker_port=8045 + docker_rum() { - docker_rum() { + read -e -p "設置登錄用戶名:" app_use + read -e -p "設置登錄密碼:" app_passwd - docker run -d \ - -p ${docker_port}:5000 \ - --name registry \ - -v /home/docker/registry:/var/lib/registry \ - -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ - --restart always \ - registry:2 + docker run -d \ + --name ${docker_name} \ + --restart=always \ + -v /home/docker/${docker_name}/downloads:/app/Downloads \ + -v /home/docker/${docker_name}/storage:/app/storage \ + -p ${docker_port}:9999 \ + ${docker_img} -u ${app_use} -p ${app_passwd} - } + } - local docker_describe="Docker Registry 是一个用于存储和分发 Docker 镜像的服务。" - local docker_url="官网介绍: https://hub.docker.com/_/registry" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app - ;; + local docker_describe="分佈式高速下載工具,支持多種協議" + local docker_url="官網介紹: https://github.com/GopeedLab/gopeed" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 46) - local docker_name="ghproxy" - local docker_img="wjqserver/ghproxy:latest" - local docker_port=8046 + ;; - docker_rum() { - docker run -d --name ghproxy --restart always -p ${docker_port}:8080 wjqserver/ghproxy:latest - } + 95|paperless) - local docker_describe="使用Go实现的GHProxy,用于加速部分地区Github仓库的拉取。" - local docker_url="官网介绍: https://github.com/WJQSERVER-STUDIO/ghproxy" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="95" - 47) + local app_name="paperless文檔管理平台" + local app_text="開源的電子文檔管理系統,它的主要用途是把你的紙質文件數字化並管理起來。" + local app_url="視頻介紹: https://docs.paperless-ngx.com/" + local docker_name="paperless-webserver-1" + local docker_port="8095" + local app_size="2" + docker_app_install() { + mkdir -p /home/docker/paperless + mkdir -p /home/docker/paperless/export + mkdir -p /home/docker/paperless/consume + cd /home/docker/paperless - local app_name="普罗米修斯监控" - local app_text="Prometheus+Grafana企业级监控系统" - local app_url="官网介绍: https://prometheus.io" - local docker_name="grafana" - local docker_port="8047" - local app_size="2" + curl -o /home/docker/paperless/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/docker-compose.postgres-tika.yml + curl -o /home/docker/paperless/docker-compose.env ${gh_proxy}raw.githubusercontent.com/paperless-ngx/paperless-ngx/refs/heads/main/docker/compose/.env - docker_app_install() { - prometheus_install - clear - ip_address - echo "已經安裝完成" - check_docker_app_ip - echo "初始用戶名密碼均為: admin" - } - - docker_app_update() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - docker_app_install - } + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/paperless/docker-compose.yml + cd /home/docker/paperless + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - docker_app_uninstall() { - docker rm -f node-exporter prometheus grafana - docker rmi -f prom/node-exporter - docker rmi -f prom/prometheus:latest - docker rmi -f grafana/grafana:latest - rm -rf /home/docker/monitoring - echo "應用已卸載" - } + docker_app_update() { + cd /home/docker/paperless/ && docker compose down --rmi all + docker_app_install + } - docker_app_plus - ;; - 48) - local docker_name="node-exporter" - local docker_img="prom/node-exporter" - local docker_port=8048 + docker_app_uninstall() { + cd /home/docker/paperless/ && docker compose down --rmi all + rm -rf /home/docker/paperless + echo "應用已卸載" + } - docker_rum() { + docker_app_plus - docker run -d \ - --name=node-exporter \ - -p ${docker_port}:9100 \ - --restart unless-stopped \ - prom/node-exporter + ;; - } - local docker_describe="这是一个普罗米修斯的主机数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/prometheus/node_exporter" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 96|2fauth) - 49) - local docker_name="cadvisor" - local docker_img="gcr.io/cadvisor/cadvisor:latest" - local docker_port=8049 + local app_id="96" - docker_rum() { + local app_name="2FAuth自託管二步驗證器" + local app_text="自託管的雙重身份驗證 (2FA) 賬戶管理和驗證碼生成工具。" + local app_url="官網: https://github.com/Bubka/2FAuth" + local docker_name="2fauth" + local docker_port="8096" + local app_size="1" - docker run -d \ - --name=cadvisor \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - --volume=/:/rootfs:ro \ - --volume=/var/run:/var/run:rw \ - --volume=/sys:/sys:ro \ - --volume=/var/lib/docker/:/var/lib/docker:ro \ - gcr.io/cadvisor/cadvisor:latest \ - -housekeeping_interval=10s \ - -docker_only=true + docker_app_install() { - } + add_yuming - local docker_describe="这是一个普罗米修斯的容器数据采集组件,请部署在被监控主机上。" - local docker_url="官网介绍: https://github.com/google/cadvisor" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + mkdir -p /home/docker/2fauth + mkdir -p /home/docker/2fauth/data + chmod -R 777 /home/docker/2fauth/ + cd /home/docker/2fauth + curl -o /home/docker/2fauth/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/2fauth-docker-compose.yml - 50) - local docker_name="changedetection" - local docker_img="dgtlmoon/changedetection.io:latest" - local docker_port=8050 + sed -i "s/8000:8000/${docker_port}:8000/g" /home/docker/2fauth/docker-compose.yml + sed -i "s/yuming.com/${yuming}/g" /home/docker/2fauth/docker-compose.yml + cd /home/docker/2fauth + docker compose up -d - docker_rum() { + ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} + block_container_port "$docker_name" "$ipv4_address" - docker run -d --restart always -p ${docker_port}:5000 \ - -v /home/docker/datastore:/datastore \ - --name changedetection dgtlmoon/changedetection.io:latest + clear + echo "已經安裝完成" + check_docker_app_ip + } - } - local docker_describe="这是一款网站变化检测、补货监控和通知的小工具" - local docker_url="官网介绍: https://github.com/dgtlmoon/changedetection.io" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + docker_app_update() { + cd /home/docker/2fauth/ && docker compose down --rmi all + docker_app_install + } - 51) - clear - send_stats "PVE開小雞" - check_disk_space 1 - curl -L ${gh_proxy}raw.githubusercontent.com/oneclickvirt/pve/main/scripts/install_pve.sh -o install_pve.sh && chmod +x install_pve.sh && bash install_pve.sh - ;; + docker_app_uninstall() { + cd /home/docker/2fauth/ && docker compose down --rmi all + rm -rf /home/docker/2fauth + echo "應用已卸載" + } + docker_app_plus - 52) - local docker_name="dpanel" - local docker_img="dpanel/dpanel:lite" - local docker_port=8052 + ;; - docker_rum() { - docker run -it -d --name dpanel --restart=always \ - -p ${docker_port}:8080 -e APP_NAME=dpanel \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /home/docker/dpanel:/dpanel \ - dpanel/dpanel:lite - } + 97|wgs) - local docker_describe="Docker可视化面板系统,提供完善的docker管理功能。" - local docker_url="官网介绍: https://github.com/donknap/dpanel" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="97" + local docker_name="wireguard" + local docker_img="lscr.io/linuxserver/wireguard:latest" + local docker_port=8097 - 53) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + docker_rum() { - docker_rum() { + read -e -p "請輸入組網的客戶端數量 (默認 5):" COUNT + COUNT=${COUNT:-5} + read -e -p "請輸入 WireGuard 網段 (默認 10.13.13.0):" NETWORK + NETWORK=${NETWORK:-10.13.13.0} - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama + PEERS=$(seq -f "wg%02g" 1 "$COUNT" | paste -sd,) - } + ip link delete wg0 &>/dev/null - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的llama3大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run llama3.2:1b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + ip_address + docker run -d \ + --name=wireguard \ + --network host \ + --cap-add=NET_ADMIN \ + --cap-add=SYS_MODULE \ + -e PUID=1000 \ + -e PGID=1000 \ + -e TZ=Etc/UTC \ + -e SERVERURL=${ipv4_address} \ + -e SERVERPORT=51820 \ + -e PEERS=${PEERS} \ + -e INTERNAL_SUBNET=${NETWORK} \ + -e ALLOWEDIPS=${NETWORK}/24 \ + -e PERSISTENTKEEPALIVE_PEERS=all \ + -e LOG_CONFS=true \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules \ + --restart=always \ + lscr.io/linuxserver/wireguard:latest - 54) - local lujing="[ -d "/www/server/panel" ]" - local panelname="AMH面板" - local panelurl="官方地址: https://amh.sh/index.htm?amh" + sleep 3 - panel_app_install() { - cd ~ - wget https://dl.amh.sh/amh.sh && bash amh.sh - } + docker exec wireguard sh -c " + f='/config/wg_confs/wg0.conf' + sed -i 's/51820/${docker_port}/g' \$f + " - panel_app_manage() { - panel_app_install - } + docker exec wireguard sh -c " + for d in /config/peer_*; do + sed -i 's/51820/${docker_port}/g' \$d/*.conf + done + " - panel_app_uninstall() { - panel_app_install - } + docker exec wireguard sh -c ' + for d in /config/peer_*; do + sed -i "/^DNS/d" "$d"/*.conf + done + ' - install_panel - ;; + docker exec wireguard sh -c ' + for d in /config/peer_*; do + for f in "$d"/*.conf; do + grep -q "^PersistentKeepalive" "$f" || \ + sed -i "/^AllowedIPs/ a PersistentKeepalive = 25" "$f" + done + done + ' + + docker exec wireguard bash -c ' + for d in /config/peer_*; do + cd "$d" || continue + conf_file=$(ls *.conf) + base_name="${conf_file%.conf}" + qrencode -o "$base_name.png" < "$conf_file" + done + ' + docker restart wireguard - 55) - frps_panel - ;; + sleep 2 + echo + echo -e "${gl_huang}所有客戶端二維碼配置:${gl_bai}" + docker exec wireguard bash -c 'for i in $(ls /config | grep peer_ | sed "s/peer_//"); do echo "--- $i ---"; /app/show-peer $i; done' + sleep 2 + echo + echo -e "${gl_huang}所有客戶端配置代碼:${gl_bai}" + docker exec wireguard sh -c 'for d in /config/peer_*; do echo "# $(basename $d) "; cat $d/*.conf; echo; done' + sleep 2 + echo -e "${gl_lv}${COUNT}個客戶端配置全部輸出,使用方法如下:${gl_bai}" + echo -e "${gl_lv}1. 手機下載wg的APP,掃描上方二維碼,可以快速連接網絡${gl_bai}" + echo -e "${gl_lv}2. Windows下載客戶端,複製配置代碼連接網絡。${gl_bai}" + echo -e "${gl_lv}3. Linux用腳本部署WG客戶端,複製配置代碼連接網絡。${gl_bai}" + echo -e "${gl_lv}官方客戶端下載方式: https://www.wireguard.com/install/${gl_bai}" + break_end - 56) - frpc_panel - ;; + } - 57) - local docker_name="ollama" - local docker_img="ghcr.io/open-webui/open-webui:ollama" - local docker_port=8053 + local docker_describe="現代化、高性能的虛擬專用網絡工具" + local docker_url="官網介紹: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 -v /home/docker/ollama:/root/.ollama -v /home/docker/ollama/open-webui:/app/backend/data --name ollama --restart always ghcr.io/open-webui/open-webui:ollama - } + 98|wgc) - local docker_describe="OpenWebUI一款大语言模型网页框架,接入全新的DeepSeek R1大语言模型" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="docker exec ollama ollama run deepseek-r1:1.5b" - local docker_passwd="" - local app_size="5" - docker_app - ;; + local app_id="98" + local docker_name="wireguardc" + local docker_img="kjlion/wireguard:alpine" + local docker_port=51820 + docker_rum() { - 58) - local app_name="Dify知识库" - local app_text="是一款开源的大语言模型(LLM) 应用开发平台。自托管训练数据用于AI生成" - local app_url="官方网站: https://docs.dify.ai/zh-hans" - local docker_name="docker-nginx-1" - local docker_port="8058" - local app_size="3" + mkdir -p /home/docker/wireguard/config/ - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langgenius/dify.git && cd dify/docker && cp .env.example .env - # sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - sed -i "s/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=${docker_port}/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/" /home/docker/dify/docker/.env + local CONFIG_FILE="/home/docker/wireguard/config/wg0.conf" - docker compose up -d - clear - echo "已經安裝完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - cd /home/docker/dify/ - git pull origin main - sed -i 's/^EXPOSE_NGINX_PORT=.*/EXPOSE_NGINX_PORT=8058/; s/^EXPOSE_NGINX_SSL_PORT=.*/EXPOSE_NGINX_SSL_PORT=8858/' /home/docker/dify/docker/.env - cd /home/docker/dify/docker/ && docker compose up -d - } - - docker_app_uninstall() { - cd /home/docker/dify/docker/ && docker compose down --rmi all - rm -rf /home/docker/dify - echo "應用已卸載" - } + # 創建目錄(如果不存在) + mkdir -p "$(dirname "$CONFIG_FILE")" - docker_app_plus + echo "請粘貼你的客戶端配置,連續按兩次回車保存:" - ;; + # 初始化變量 + input="" + empty_line_count=0 - 59) - local app_name="New API" - local app_text="新一代大模型网关与AI资产管理系统" - local app_url="官方网站: https://github.com/Calcium-Ion/new-api" - local docker_name="new-api" - local docker_port="8059" - local app_size="3" + # 逐行讀取用戶輸入 + while IFS= read -r line; do + if [[ -z "$line" ]]; then + ((empty_line_count++)) + if [[ $empty_line_count -ge 2 ]]; then + break + fi + else + empty_line_count=0 + input+="$line"$'\n' + fi + done - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/Calcium-Ion/new-api.git && cd new-api + # 寫入配置文件 + echo "$input" > "$CONFIG_FILE" - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + echo "客戶端配置已保存到$CONFIG_FILE" + ip link delete wg0 &>/dev/null - docker compose up -d - clear - echo "已經安裝完成" - check_docker_app_ip - } + docker run -d \ + --name wireguardc \ + --network host \ + --cap-add NET_ADMIN \ + --cap-add SYS_MODULE \ + -v /home/docker/wireguard/config:/config \ + -v /lib/modules:/lib/modules:ro \ + --restart=always \ + kjlion/wireguard:alpine - docker_app_update() { - cd /home/docker/new-api/ && docker compose down --rmi all - cd /home/docker/new-api/ - git pull origin main - sed -i -e "s/- \"3000:3000\"/- \"${docker_port}:3000\"/g" \ - -e 's/container_name: redis/container_name: redis-new-api/g' \ - -e 's/container_name: mysql/container_name: mysql-new-api/g' \ - docker-compose.yml + sleep 3 - docker compose up -d - clear - echo "已經安裝完成" - check_docker_app_ip + docker logs wireguardc - } + break_end - docker_app_uninstall() { - cd /home/docker/new-api/ && docker compose down --rmi all - rm -rf /home/docker/new-api - echo "應用已卸載" - } + } - docker_app_plus + local docker_describe="現代化、高性能的虛擬專用網絡工具" + local docker_url="官網介紹: https://www.wireguard.com/" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - ;; + ;; - 60) + 99|dsm) - local app_name="JumpServer开源堡垒机" - local app_text="是一个开源的特权访问管理 (PAM) 工具,该程序占用80端口不支持添加域名访问了" - local app_url="官方介绍: https://github.com/jumpserver/jumpserver" - local docker_name="jms_web" - local docker_port="80" - local app_size="2" + local app_id="99" - docker_app_install() { - curl -sSL ${gh_proxy}github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash - clear - echo "已經安裝完成" - check_docker_app_ip - echo "初始用戶名: admin" - echo "初始密碼: ChangeMe" - } + local app_name="dsm群暉虛擬機" + local app_text="Docker容器中的虛擬DSM" + local app_url="官網: https://github.com/vdsm/virtual-dsm" + local docker_name="dsm" + local docker_port="8099" + local app_size="16" + docker_app_install() { - docker_app_update() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh upgrade - echo "應用已更新" - } + read -e -p "設置 CPU 核數 (默認 2):" CPU_CORES + local CPU_CORES=${CPU_CORES:-2} + read -e -p "設置內存大小 (默認 4G):" RAM_SIZE + local RAM_SIZE=${RAM_SIZE:-4} - docker_app_uninstall() { - cd /opt/jumpserver-installer*/ - ./jmsctl.sh uninstall - cd /opt - rm -rf jumpserver-installer*/ - rm -rf jumpserver - echo "應用已卸載" - } + mkdir -p /home/docker/dsm + mkdir -p /home/docker/dsm/dev + chmod -R 777 /home/docker/dsm/ + cd /home/docker/dsm - docker_app_plus - ;; + curl -o /home/docker/dsm/docker-compose.yml ${gh_proxy}raw.githubusercontent.com/kejilion/docker/main/dsm-docker-compose.yml - 61) - local docker_name="libretranslate" - local docker_img="libretranslate/libretranslate:latest" - local docker_port=8061 + sed -i "s/5000:5000/${docker_port}:5000/g" /home/docker/dsm/docker-compose.yml + sed -i "s|CPU_CORES: "2"|CPU_CORES: "${CPU_CORES}"|g" /home/docker/dsm/docker-compose.yml + sed -i "s|RAM_SIZE: "2G"|RAM_SIZE: "${RAM_SIZE}G"|g" /home/docker/dsm/docker-compose.yml + cd /home/docker/dsm + docker compose up -d - docker_rum() { + clear + echo "已經安裝完成" + check_docker_app_ip + } - docker run -d \ - -p ${docker_port}:5000 \ - --name libretranslate \ - libretranslate/libretranslate \ - --load-only ko,zt,zh,en,ja,pt,es,fr,de,ru - } + docker_app_update() { + cd /home/docker/dsm/ && docker compose down --rmi all + docker_app_install + } - local docker_describe="免费开源机器翻译 API,完全自托管,它的翻译引擎由开源Argos Translate库提供支持。" - local docker_url="官网介绍: https://github.com/LibreTranslate/LibreTranslate" - local docker_use="" - local docker_passwd="" - local app_size="5" - docker_app - ;; + docker_app_uninstall() { + cd /home/docker/dsm/ && docker compose down --rmi all + rm -rf /home/docker/dsm + echo "應用已卸載" + } + docker_app_plus - 62) - local app_name="RAGFlow知识库" - local app_text="基于深度文档理解的开源 RAG(检索增强生成)引擎" - local app_url="官方网站: https://github.com/infiniflow/ragflow" - local docker_name="ragflow-server" - local docker_port="8062" - local app_size="8" + ;; - docker_app_install() { - install git - mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/infiniflow/ragflow.git && cd ragflow/docker - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - clear - echo "已經安裝完成" - check_docker_app_ip - } - - docker_app_update() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - cd /home/docker/ragflow/ - git pull origin main - cd /home/docker/ragflow/docker/ - sed -i "s/- 80:80/- ${docker_port}:80/; /- 443:443/d" docker-compose.yml - docker compose up -d - } - docker_app_uninstall() { - cd /home/docker/ragflow/docker/ && docker compose down --rmi all - rm -rf /home/docker/ragflow - echo "應用已卸載" - } - docker_app_plus + 100|syncthing) - ;; + local app_id="100" + local docker_name="syncthing" + local docker_img="syncthing/syncthing:latest" + local docker_port=8100 + docker_rum() { + docker run -d \ + --name=syncthing \ + --hostname=my-syncthing \ + --restart=always \ + -p ${docker_port}:8384 \ + -p 22000:22000/tcp \ + -p 22000:22000/udp \ + -p 21027:21027/udp \ + -v /home/docker/syncthing:/var/syncthing \ + syncthing/syncthing:latest + } - 63) - local docker_name="open-webui" - local docker_img="ghcr.io/open-webui/open-webui:main" - local docker_port=8063 + local docker_describe="開源的點對點文件同步工具,類似於 Dropbox、Resilio Sync,但完全去中心化。" + local docker_url="官網介紹: https://github.com/syncthing/syncthing" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - docker_rum() { + ;; - docker run -d -p ${docker_port}:8080 -v /home/docker/open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main - } + 101|moneyprinterturbo) + local app_id="101" + local app_name="AI視頻生成工具" + local app_text="MoneyPrinterTurbo是一款使用AI大模型合成高清短視頻的工具" + local app_url="官方網站: https://github.com/harry0703/MoneyPrinterTurbo" + local docker_name="moneyprinterturbo" + local docker_port="8101" + local app_size="3" - local docker_describe="OpenWebUI一款大语言模型网页框架,官方精简版本,支持各大模型API接入" - local docker_url="官网介绍: https://github.com/open-webui/open-webui" - local docker_use="" - local docker_passwd="" - local app_size="3" - docker_app - ;; + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git && cd MoneyPrinterTurbo/ + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml - 64) - local docker_name="it-tools" - local docker_img="corentinth/it-tools:latest" - local docker_port=8064 + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - docker_rum() { - docker run -d --name it-tools --restart unless-stopped -p ${docker_port}:80 corentinth/it-tools:latest - } + docker_app_update() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + cd /home/docker/MoneyPrinterTurbo/ - local docker_describe="对开发人员和 IT 工作者来说非常有用的工具" - local docker_url="官网介绍: https://github.com/CorentinTh/it-tools" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + git pull ${gh_proxy}github.com/harry0703/MoneyPrinterTurbo.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/MoneyPrinterTurbo/docker-compose.yml + cd /home/docker/MoneyPrinterTurbo/ && docker compose up -d + } + docker_app_uninstall() { + cd /home/docker/MoneyPrinterTurbo/ && docker compose down --rmi all + rm -rf /home/docker/MoneyPrinterTurbo + echo "應用已卸載" + } - 65) - local docker_name="n8n" - local docker_img="docker.n8n.io/n8nio/n8n" - local docker_port=8065 + docker_app_plus - docker_rum() { + ;; - add_yuming - mkdir -p /home/docker/n8n - chmod -R 777 /home/docker/n8n - - docker run -d --name n8n \ - --restart always \ - -p ${docker_port}:5678 \ - -v /home/docker/n8n:/home/node/.n8n \ - -e N8N_HOST=${yuming} \ - -e N8N_PORT=5678 \ - -e N8N_PROTOCOL=https \ - -e N8N_WEBHOOK_URL=https://${yuming}/ \ - docker.n8n.io/n8nio/n8n - ldnmp_Proxy ${yuming} 127.0.0.1 ${docker_port} - block_container_port "$docker_name" "$ipv4_address" - } + 102|vocechat) - local docker_describe="是一款功能强大的自动化工作流平台" - local docker_url="官网介绍: https://github.com/n8n-io/n8n" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + local app_id="102" + local docker_name="vocechat-server" + local docker_img="privoce/vocechat-server:latest" + local docker_port=8102 - 66) - yt_menu_pro - ;; + docker_rum() { + docker run -d --restart=always \ + -p ${docker_port}:3000 \ + --name vocechat-server \ + -v /home/docker/vocechat/data:/home/vocechat-server/data \ + privoce/vocechat-server:latest - 67) - local docker_name="ddns-go" - local docker_img="jeessy/ddns-go" - local docker_port=8067 + } - docker_rum() { - docker run -d \ - --name ddns-go \ - --restart=always \ - -p ${docker_port}:9876 \ - -v /home/docker/ddns-go:/root \ - jeessy/ddns-go + local docker_describe="是一款支持獨立部署的個人云社交媒體聊天服務" + local docker_url="官網介紹: https://github.com/Privoce/vocechat-web" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - } + ;; - local docker_describe="自动将你的公网 IP(IPv4/IPv6)实时更新到各大 DNS 服务商,实现动态域名解析。" - local docker_url="官网介绍: https://github.com/jeessy2/ddns-go" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; - 68) - local docker_name="allinssl" - local docker_img="allinssl/allinssl:latest" - local docker_port=8068 + 103|umami) + local app_id="103" + local app_name="Umami網站統計工具" + local app_text="開源、輕量、隱私友好的網站分析工具,類似於GoogleAnalytics。" + local app_url="官方網站: https://github.com/umami-software/umami" + local docker_name="umami-umami-1" + local docker_port="8103" + local app_size="1" - docker_rum() { - docker run -itd --name allinssl -p ${docker_port}:8888 -v /home/docker/allinssl/data:/www/allinssl/data -e ALLINSSL_USER=allinssl -e ALLINSSL_PWD=allinssldocker -e ALLINSSL_URL=allinssl allinssl/allinssl:latest - } + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/umami-software/umami.git && cd umami + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/umami/docker-compose.yml - local docker_describe="开源免费的 SSL 证书自动化管理平台" - local docker_url="官网介绍: https://allinssl.com" - local docker_use="echo \"安全入口: /allinssl\"" - local docker_passwd="echo \"用户名: allinssl 密码: allinssldocker\"" - local app_size="1" - docker_app - ;; + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + echo "初始用戶名: admin" + echo "初始密碼: umami" + } + docker_app_update() { + cd /home/docker/umami/ && docker compose down --rmi all + cd /home/docker/umami/ + git pull ${gh_proxy}github.com/umami-software/umami.git main > /dev/null 2>&1 + sed -i "s/8501:8501/${docker_port}:8501/g" /home/docker/umami/docker-compose.yml + cd /home/docker/umami/ && docker compose up -d + } - 69) - local docker_name="sftpgo" - local docker_img="drakkan/sftpgo:latest" - local docker_port=8069 + docker_app_uninstall() { + cd /home/docker/umami/ && docker compose down --rmi all + rm -rf /home/docker/umami + echo "應用已卸載" + } - docker_rum() { + docker_app_plus - mkdir -p /home/docker/sftpgo/data - mkdir -p /home/docker/sftpgo/config - chown -R 1000:1000 /home/docker/sftpgo + ;; - docker run -d \ - --name sftpgo \ - --restart=always \ - -p ${docker_port}:8080 \ - -p 22022:2022 \ - --mount type=bind,source=/home/docker/sftpgo/data,target=/srv/sftpgo \ - --mount type=bind,source=/home/docker/sftpgo/config,target=/var/lib/sftpgo \ - drakkan/sftpgo:latest + 104|nginx-stream) + stream_panel + ;; - } - local docker_describe="开源免费随时随地SFTP FTP WebDAV 文件传输工具" - local docker_url="官网介绍: https://sftpgo.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + 105|siyuan) + local app_id="105" + local docker_name="siyuan" + local docker_img="b3log/siyuan" + local docker_port=8105 - 70) - local docker_name="astrbot" - local docker_img="soulter/astrbot:latest" - local docker_port=8070 + docker_rum() { - docker_rum() { + read -e -p "設置登錄密碼:" app_passwd - mkdir -p /home/docker/astrbot/data + docker run -d \ + --name siyuan \ + --restart=always \ + -v /home/docker/siyuan/workspace:/siyuan/workspace \ + -p ${docker_port}:6806 \ + -e PUID=1001 \ + -e PGID=1002 \ + b3log/siyuan \ + --workspace=/siyuan/workspace/ \ + --accessAuthCode="${app_passwd}" - sudo docker run -d \ - -p ${docker_port}:6185 \ - -p 6195:6195 \ - -p 6196:6196 \ - -p 6199:6199 \ - -p 11451:11451 \ - -v /home/docker/astrbot/data:/AstrBot/data \ - --restart unless-stopped \ - --name astrbot \ - soulter/astrbot:latest + } - } + local docker_describe="思源筆記是一款隱私優先的知識管理系統" + local docker_url="官網介紹: https://github.com/siyuan-note/siyuan" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - local docker_describe="开源AI聊天机器人框架,支持微信,QQ,TG接入AI大模型" - local docker_url="官网介绍: https://astrbot.app/" - local docker_use="echo \"用户名: astrbot 密码: astrbot\"" - local docker_passwd="" - local app_size="1" - docker_app - ;; + ;; - 71) - local docker_name="navidrome" - local docker_img="deluan/navidrome:latest" - local docker_port=8071 + 106|drawnix) - docker_rum() { + local app_id="106" + local docker_name="drawnix" + local docker_img="pubuzhixing/drawnix" + local docker_port=8106 - docker run -d \ - --name navidrome \ - --restart=unless-stopped \ - --user $(id -u):$(id -g) \ - -v /home/docker/navidrome/music:/music \ - -v /home/docker/navidrome/data:/data \ - -p ${docker_port}:4533 \ - -e ND_LOGLEVEL=info \ - deluan/navidrome:latest + docker_rum() { - } + docker run -d \ + --restart=always \ + --name drawnix \ + -p ${docker_port}:80 \ + pubuzhixing/drawnix - local docker_describe="是一个轻量、高性能的音乐流媒体服务器" - local docker_url="官网介绍: https://www.navidrome.org/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="是一款強大的開源白板工具,集成思維導圖、流程圖等。" + local docker_url="官網介紹: https://github.com/plait-board/drawnix" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 72) + ;; - local docker_name="bitwarden" - local docker_img="vaultwarden/server" - local docker_port=8072 - docker_rum() { + 107|pansou) - docker run -d \ - --name bitwarden \ - --restart always \ - -p ${docker_port}:80 \ - -v /home/docker/bitwarden/data:/data \ - vaultwarden/server + local app_id="107" + local docker_name="pansou" + local docker_img="ghcr.io/fish2018/pansou-web" + local docker_port=8107 - } + docker_rum() { - local docker_describe="一个你可以控制数据的密码管理器" - local docker_url="官网介绍: https://bitwarden.com/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker run -d \ + --name pansou \ + --restart=always \ + -p ${docker_port}:80 \ + -v /home/docker/pansou/data:/app/data \ + -v /home/docker/pansou/logs:/app/logs \ + -e ENABLED_PLUGINS="hunhepan,jikepan,panwiki,pansearch,panta,qupansou, +susu,thepiratebay,wanou,xuexizhinan,panyq,zhizhen,labi,muou,ouge,shandian, +duoduo,huban,cyg,erxiao,miaoso,fox4k,pianku,clmao,wuji,cldi,xiaozhang, +libvio,leijing,xb6v,xys,ddys,hdmoli,yuhuage,u3c3,javdb,clxiong,jutoushe, +sdso,xiaoji,xdyh,haisou,bixin,djgou,nyaa,xinjuc,aikanzy,qupanshe,xdpan, +discourse,yunsou,ahhhhfs,nsgame,gying" \ + ghcr.io/fish2018/pansou-web + } - ;; + local docker_describe="PanSou是一個高性能的網盤資源搜索API服務。" + local docker_url="官網介紹: https://github.com/fish2018/pansou" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 73) - local docker_name="libretv" - local docker_img="bestzwei/libretv:latest" - local docker_port=8073 - docker_rum() { + 108|langbot) + local app_id="108" + local app_name="LangBot聊天機器人" + local app_text="是一個開源的大語言模型原生即時通信機器人開發平台" + local app_url="官方網站: https://github.com/langbot-app/LangBot" + local docker_name="langbot_plugin_runtime" + local docker_port="8108" + local app_size="1" - read -e -p "設置LibreTV的登錄密碼:" app_passwd + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/langbot-app/LangBot && cd LangBot/docker + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml - docker run -d \ - --name libretv \ - --restart unless-stopped \ - -p ${docker_port}:8080 \ - -e PASSWORD=${app_passwd} \ - bestzwei/libretv:latest + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/LangBot/docker && docker compose down --rmi all + cd /home/docker/LangBot/ + git pull ${gh_proxy}github.com/langbot-app/LangBot main > /dev/null 2>&1 + sed -i "s/5300:5300/${docker_port}:5300/g" /home/docker/LangBot/docker/docker-compose.yaml + cd /home/docker/LangBot/docker/ && docker compose up -d + } - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/LibreSpark/LibreTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/LangBot/docker/ && docker compose down --rmi all + rm -rf /home/docker/LangBot + echo "應用已卸載" + } - ;; + docker_app_plus + ;; - 74) - local docker_name="moontv" - local docker_img="ghcr.io/senshinya/moontv:latest" - local docker_port=8074 + 109|zfile) - docker_rum() { + local app_id="109" + local docker_name="zfile" + local docker_img="zhaojun1998/zfile:latest" + local docker_port=8109 - read -e -p "設置MoonTV的登錄密碼:" app_passwd + docker_rum() { - docker run -d \ - --name moontv \ - --restart unless-stopped \ - -p ${docker_port}:3000 \ - -e PASSWORD=${app_passwd} \ - ghcr.io/senshinya/moontv:latest - } + docker run -d --name=zfile --restart=always \ + -p ${docker_port}:8080 \ + -v /home/docker/zfile/db:/root/.zfile-v4/db \ + -v /home/docker/zfile/logs:/root/.zfile-v4/logs \ + -v /home/docker/zfile/file:/data/file \ + -v /home/docker/zfile/application.properties:/root/.zfile-v4/application.properties \ + zhaojun1998/zfile:latest - local docker_describe="免费在线视频搜索与观看平台" - local docker_url="官网介绍: https://github.com/senshinya/MoonTV" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app - ;; + } + local docker_describe="是一個適用於個人或小團隊的在線網盤程序。" + local docker_url="官網介紹: https://github.com/zfile-dev/zfile" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app - 75) + ;; - local docker_name="melody" - local docker_img="foamzou/melody:latest" - local docker_port=8075 - docker_rum() { + 110|karakeep) + local app_id="110" + local app_name="karakeep書籤管理" + local app_text="是一款可自行託管的書籤應用,帶有人工智能功能,專為數據囤積者而設計。" + local app_url="官方網站: https://github.com/karakeep-app/karakeep" + local docker_name="docker-web-1" + local docker_port="8110" + local app_size="1" - docker run -d \ - --name melody \ - --restart unless-stopped \ - -p ${docker_port}:5566 \ - -v /home/docker/melody/.profile:/app/backend/.profile \ - foamzou/melody:latest + docker_app_install() { + install git + mkdir -p /home/docker/ && cd /home/docker/ && git clone ${gh_proxy}github.com/karakeep-app/karakeep.git && cd karakeep/docker && cp .env.sample .env + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + docker compose up -d + clear + echo "已經安裝完成" + check_docker_app_ip + } - } + docker_app_update() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + cd /home/docker/karakeep/ + git pull ${gh_proxy}github.com/karakeep-app/karakeep.git main > /dev/null 2>&1 + sed -i "s/3000:3000/${docker_port}:3000/g" /home/docker/karakeep/docker/docker-compose.yml + cd /home/docker/karakeep/docker/ && docker compose up -d + } - local docker_describe="你的音乐精灵,旨在帮助你更好地管理音乐。" - local docker_url="官网介绍: https://github.com/foamzou/melody" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + docker_app_uninstall() { + cd /home/docker/karakeep/docker/ && docker compose down --rmi all + rm -rf /home/docker/karakeep + echo "應用已卸載" + } + docker_app_plus - ;; + ;; - 76) - local docker_name="dosgame" - local docker_img="oldiy/dosgame-web-docker:latest" - local docker_port=8076 + 111|convertx) - docker_rum() { - docker run -d \ - --name dosgame \ - --restart unless-stopped \ - -p ${docker_port}:262 \ - oldiy/dosgame-web-docker:latest + local app_id="111" + local docker_name="convertx" + local docker_img="ghcr.io/c4illin/convertx:latest" + local docker_port=8111 - } + docker_rum() { - local docker_describe="是一个中文DOS游戏合集网站" - local docker_url="官网介绍: https://github.com/rwv/chinese-dos-games" - local docker_use="" - local docker_passwd="" - local app_size="2" - docker_app + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:3000 \ + -v /home/docker/convertx:/app/data \ + ${docker_img} + } - ;; + local docker_describe="是一個功能強大的多格式文件轉換工具(支持文檔、圖像、音頻視頻等)強烈建議添加域名訪問" + local docker_url="項目地址: https://github.com/c4illin/ConvertX" + local docker_use="" + local docker_passwd="" + local app_size="2" + docker_app - 77) + ;; - local docker_name="xunlei" - local docker_img="cnk3x/xunlei" - local docker_port=8077 - docker_rum() { + 112|lucky) - read -e -p "設定${docker_name}的登錄用戶名:" app_use - read -e -p "設定${docker_name}的登錄密碼:" app_passwd + local app_id="112" + local docker_name="lucky" + local docker_img="gdy666/lucky:v2" + # 由於 Lucky 使用 host 網絡模式,這裡的端口僅作記錄/說明參考,實際由應用自身控制(默認16601) + local docker_port=8112 - docker run -d \ - --name xunlei \ - --restart unless-stopped \ - --privileged \ - -e XL_DASHBOARD_USERNAME=${app_use} \ - -e XL_DASHBOARD_PASSWORD=${app_passwd} \ - -v /home/docker/xunlei/data:/xunlei/data \ - -v /home/docker/xunlei/downloads:/xunlei/downloads \ - -p ${docker_port}:2345 \ - cnk3x/xunlei + docker_rum() { - } + docker run -d --name=${docker_name} --restart=always \ + --network host \ + -v /home/docker/lucky/conf:/app/conf \ + -v /var/run/docker.sock:/var/run/docker.sock \ + ${docker_img} - local docker_describe="迅雷你的离线高速BT磁力下载工具" - local docker_url="官网介绍: https://github.com/cnk3x/xunlei" - local docker_use="echo \"手机登录迅雷,再输入邀请码,邀请码: 迅雷牛通\"" - local docker_passwd="" - local app_size="1" - docker_app + echo "正在等待 Lucky 初始化..." + sleep 10 + docker exec lucky /app/lucky -rSetHttpAdminPort ${docker_port} - ;; + } + local docker_describe="Lucky 是一個大內網穿透及端口轉發管理工具,支持 DDNS、反向代理、WOL 等功能。" + local docker_url="項目地址: https://github.com/gdy666/lucky" + local docker_use="echo \"默認賬號密碼: 666\"" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 78) - local app_name="PandaWiki" - local app_text="PandaWiki是一款AI大模型驱动的开源智能文档管理系统,强烈建议不要自定义端口部署。" - local app_url="官方介绍: https://github.com/chaitin/PandaWiki" - local docker_name="panda-wiki-nginx" - local docker_port="2443" - local app_size="2" + 113|firefox) - docker_app_install() { - bash -c "$(curl -fsSLk https://release.baizhi.cloud/panda-wiki/manager.sh)" - } + local app_id="113" + local docker_name="firefox" + local docker_img="jlesage/firefox:latest" + local docker_port=8113 - docker_app_update() { - docker_app_install - } + docker_rum() { + read -e -p "設置登錄密碼:" admin_password - docker_app_uninstall() { - docker_app_install - } + docker run -d --name=${docker_name} --restart=always \ + -p ${docker_port}:5800 \ + -v /home/docker/firefox:/config:rw \ + -e ENABLE_CJK_FONT=1 \ + -e WEB_AUDIO=1 \ + -e VNC_PASSWORD="${admin_password}" \ + ${docker_img} + } - docker_app_plus - ;; + local docker_describe="是一個運行在 Docker 中的 Firefox 瀏覽器,支持通過網頁直接訪問桌面版瀏覽器界面。" + local docker_url="項目地址: https://github.com/jlesage/docker-firefox" + local docker_use="" + local docker_passwd="" + local app_size="1" + docker_app + ;; - 79) + b) + clear + send_stats "全部應用備份" - local docker_name="beszel" - local docker_img="henrygd/beszel" - local docker_port=8079 + local backup_filename="app_$(date +"%Y%m%d%H%M%S").tar.gz" + echo -e "${gl_huang}正在備份$backup_filename ...${gl_bai}" + cd / && tar czvf "$backup_filename" home - docker_rum() { + while true; do + clear + echo "備份文件已創建: /$backup_filename" + read -e -p "要傳送備份數據到遠程服務器嗎? (Y/N):" choice + case "$choice" in + [Yy]) + read -e -p "請輸入遠端服務器IP:" remote_ip + read -e -p "目標服務器SSH端口 [默認22]:" TARGET_PORT + local TARGET_PORT=${TARGET_PORT:-22} - mkdir -p /home/docker/beszel && \ - docker run -d \ - --name beszel \ - --restart=unless-stopped \ - -v /home/docker/beszel:/beszel_data \ - -p ${docker_port}:8090 \ - henrygd/beszel + if [ -z "$remote_ip" ]; then + echo "錯誤: 請輸入遠端服務器IP。" + continue + fi + local latest_tar=$(ls -t /app*.tar.gz | head -1) + if [ -n "$latest_tar" ]; then + ssh-keygen -f "/root/.ssh/known_hosts" -R "$remote_ip" + sleep 2 # 添加等待时间 + scp -P "$TARGET_PORT" -o StrictHostKeyChecking=no "$latest_tar" "root@$remote_ip:/" + echo "文件已傳送至遠程服務器/根目錄。" + else + echo "未找到要傳送的文件。" + fi + break + ;; + *) + echo "注意: 目前備份僅包含docker項目,不包含寶塔,1panel等建站面板的數據備份。" + break + ;; + esac + done - } + ;; - local docker_describe="Beszel轻量易用的服务器监控" - local docker_url="官网介绍: https://beszel.dev/zh/" - local docker_use="" - local docker_passwd="" - local app_size="1" - docker_app + r) + root_use + send_stats "全部應用還原" + echo "可用的應用備份" + echo "-------------------------" + ls -lt /app*.gz | awk '{print $NF}' + echo "" + read -e -p "回車鍵還原最新的備份,輸入備份文件名還原指定的備份,輸入0退出:" filename - ;; + if [ "$filename" == "0" ]; then + break_end + linux_panel + fi + + # 如果用戶沒有輸入文件名,使用最新的壓縮包 + if [ -z "$filename" ]; then + local filename=$(ls -t /app*.tar.gz | head -1) + fi + + if [ -n "$filename" ]; then + echo -e "${gl_huang}正在解壓$filename ...${gl_bai}" + cd / && tar -xzf "$filename" + echo "應用數據已還原,目前請手動進入指定應用菜單,更新應用,即可還原應用。" + else + echo "沒有找到壓縮包。" + fi + ;; - 0) - kejilion - ;; - *) - echo "無效的輸入!" - ;; - esac - break_end + 0) + kejilion + ;; + *) + cd ~ + install git + if [ ! -d apps/.git ]; then + git clone ${gh_proxy}github.com/kejilion/apps.git + else + cd apps + # git pull origin main > /dev/null 2>&1 + git pull ${gh_proxy}github.com/kejilion/apps.git main > /dev/null 2>&1 + fi + local custom_app="$HOME/apps/${sub_choice}.conf" + if [ -f "$custom_app" ]; then + . "$custom_app" + else + echo -e "${gl_hong}錯誤: 未找到編號為${sub_choice}的應用配置${gl_bai}" + fi + ;; + esac + break_end + sub_choice="" - done +done } + linux_work() { while true; do @@ -10748,9 +13237,9 @@ linux_work() { while true; do clear if grep -q 'tmux attach-session -t sshd || tmux new-session -s sshd' ~/.bashrc; then - local tmux_sshd_status="${gl_lv}开启${gl_bai}" + local tmux_sshd_status="${gl_lv}開啟${gl_bai}" else - local tmux_sshd_status="${gl_hui}关闭${gl_bai}" + local tmux_sshd_status="${gl_hui}關閉${gl_bai}" fi send_stats "SSH常駐模式" echo -e "SSH常駐模式${tmux_sshd_status}" @@ -10771,7 +13260,7 @@ linux_work() { tmux_run ;; 2) - sed -i '/# 自动进入 tmux 会话/,+4d' ~/.bashrc + sed -i '/# 自動進入 tmux 會話/,+4d' ~/.bashrc tmux kill-window -t sshd ;; *) @@ -10782,7 +13271,7 @@ linux_work() { ;; 22) - read -e -p "請輸入你創建或進入的工作區名稱,如1001 kj001 work1:" SESSION_NAME + read -e -p "請輸入你創建或進入的工作區名稱,如1​​001 kj001 work1:" SESSION_NAME tmux_run send_stats "自定義工作區" ;; @@ -10823,6 +13312,101 @@ linux_work() { +# 智能切換鏡像源函數 +switch_mirror() { + # 可選參數,默認為 false + local upgrade_software=${1:-false} + local clean_cache=${2:-false} + + # 獲取用戶國家 + local country + country=$(curl -s ipinfo.io/country) + + echo "檢測到國家:$country" + + if [ "$country" = "CN" ]; then + echo "使用國內鏡像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --source mirrors.huaweicloud.com \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + else + echo "使用官方鏡像源..." + bash <(curl -sSL https://linuxmirrors.cn/main.sh) \ + --use-official-source true \ + --protocol https \ + --use-intranet-source false \ + --backup true \ + --upgrade-software "$upgrade_software" \ + --clean-cache "$clean_cache" \ + --ignore-backup-tips \ + --install-epel true \ + --pure-mode + fi +} + + +fail2ban_panel() { + root_use + send_stats "ssh防禦" + while true; do + + check_f2b_status + echo -e "SSH防禦程序$check_f2b_status" + echo "fail2ban是一個SSH防止暴力破解工具" + echo "官網介紹:${gh_proxy}github.com/fail2ban/fail2ban" + echo "------------------------" + echo "1. 安裝防禦程序" + echo "------------------------" + echo "2. 查看SSH攔截記錄" + echo "3. 日誌實時監控" + echo "------------------------" + echo "9. 卸載防禦程序" + echo "------------------------" + echo "0. 返回上一級選單" + echo "------------------------" + read -e -p "請輸入你的選擇:" sub_choice + case $sub_choice in + 1) + f2b_install_sshd + cd ~ + f2b_status + break_end + ;; + 2) + echo "------------------------" + f2b_sshd + echo "------------------------" + break_end + ;; + 3) + tail -f /var/log/fail2ban.log + break + ;; + 9) + remove fail2ban + rm -rf /etc/fail2ban + echo "Fail2Ban防禦程序已卸載" + break + ;; + *) + break + ;; + esac + done + +} + + + + + linux_Settings() { @@ -10846,7 +13430,7 @@ linux_Settings() { echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}21. ${gl_bai}本機host解析${gl_kjlan}22. ${gl_bai}SSH防禦程序" echo -e "${gl_kjlan}23. ${gl_bai}限流自動關機${gl_kjlan}24. ${gl_bai}ROOT私鑰登錄模式" - echo -e "${gl_kjlan}25. ${gl_bai}TG-bot系統監控預警${gl_kjlan}26. ${gl_bai}修復OpenSSH高危漏洞(岫源)" + echo -e "${gl_kjlan}25. ${gl_bai}TG-bot系統監控預警${gl_kjlan}26. ${gl_bai}修復OpenSSH高危漏洞" echo -e "${gl_kjlan}27. ${gl_bai}紅帽系Linux內核升級${gl_kjlan}28. ${gl_bai}Linux系統內核參數優化${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}29. ${gl_bai}病毒掃描工具${gl_huang}★${gl_bai} ${gl_kjlan}30. ${gl_bai}文件管理器" echo -e "${gl_kjlan}------------------------" @@ -10854,6 +13438,7 @@ linux_Settings() { echo -e "${gl_kjlan}33. ${gl_bai}設置系統回收站${gl_kjlan}34. ${gl_bai}系統備份與恢復" echo -e "${gl_kjlan}35. ${gl_bai}ssh遠程連接工具${gl_kjlan}36. ${gl_bai}硬盤分區管理工具" echo -e "${gl_kjlan}37. ${gl_bai}命令行歷史記錄${gl_kjlan}38. ${gl_bai}rsync遠程同步工具" + echo -e "${gl_kjlan}39. ${gl_bai}命令收藏夾${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}------------------------" echo -e "${gl_kjlan}41. ${gl_bai}留言板${gl_kjlan}66. ${gl_bai}一條龍系統調優${gl_huang}★${gl_bai}" echo -e "${gl_kjlan}99. ${gl_bai}重啟服務器${gl_kjlan}100. ${gl_bai}隱私與安全" @@ -11049,6 +13634,8 @@ EOF useradd -m -s /bin/bash "$new_username" passwd "$new_username" + install sudo + echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers passwd -l root @@ -11064,13 +13651,14 @@ EOF clear echo "設置v4/v6優先級" echo "------------------------" - local ipv6_disabled=$(sysctl -n net.ipv6.conf.all.disable_ipv6) - if [ "$ipv6_disabled" -eq 1 ]; then + + if grep -Eq '^\s*precedence\s+::ffff:0:0/96\s+100\s*$' /etc/gai.conf 2>/dev/null; then echo -e "當前網絡優先級設置:${gl_huang}IPv4${gl_bai}優先" else echo -e "當前網絡優先級設置:${gl_huang}IPv6${gl_bai}優先" fi + echo "" echo "------------------------" echo "1. IPv4 優先 2. IPv6 優先 3. IPv6 修復工具" @@ -11081,12 +13669,10 @@ EOF case $choice in 1) - sysctl -w net.ipv6.conf.all.disable_ipv6=1 > /dev/null 2>&1 - echo "已切換為 IPv4 優先" - send_stats "已切換為 IPv4 優先" + prefer_ipv4 ;; 2) - sysctl -w net.ipv6.conf.all.disable_ipv6=0 > /dev/null 2>&1 + rm -f /etc/gai.conf echo "已切換為 IPv6 優先" send_stats "已切換為 IPv6 優先" ;; @@ -11165,7 +13751,7 @@ EOF send_stats "用戶管理" echo "用戶列表" echo "----------------------------------------------------------------------------" - printf "%-24s %-34s %-20s %-10s\n" "用户名" "用户权限" "用户组" "sudo权限" + printf "%-24s %-34s %-20s %-10s\n" "使用者名稱" "用戶權限" "用戶組" "sudo權限" while IFS=: read -r username _ userid groupid _ _ homedir shell; do local groups=$(groups "$username" | cut -d : -f 2) local sudo_status=$(sudo -n -lU "$username" 2>/dev/null | grep -q '(ALL : ALL)' && echo "Yes" || echo "No") @@ -11209,6 +13795,8 @@ EOF # 賦予新用戶sudo權限 echo "$new_username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + install sudo + echo "操作已完成。" ;; @@ -11216,6 +13804,8 @@ EOF read -e -p "請輸入用戶名:" username # 賦予新用戶sudo權限 echo "$username ALL=(ALL:ALL) ALL" | tee -a /etc/sudoers + + install sudo ;; 4) read -e -p "請輸入用戶名:" username @@ -11420,7 +14010,7 @@ EOF echo "選擇更新源區域" echo "接入LinuxMirrors切換系統更新源" echo "------------------------" - echo "1. 中國大陸【默認】 2. 中國大陸【教育網】 3. 海外地區" + echo "1. 中國大陸【默認】 2. 中國大陸【教育網】 3. 海外地區 4. 智能切換更新源" echo "------------------------" echo "0. 返回上一級選單" echo "------------------------" @@ -11439,6 +14029,11 @@ EOF send_stats "海外源" bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad ;; + 4) + send_stats "智能切換更新源" + switch_mirror false false + ;; + *) echo "已取消" ;; @@ -11550,63 +14145,7 @@ EOF ;; 22) - root_use - send_stats "ssh防禦" - while true; do - if [ -x "$(command -v fail2ban-client)" ] ; then - clear - remove fail2ban - rm -rf /etc/fail2ban - else - clear - rm -f /path/to/fail2ban/config/fail2ban/jail.d/sshd.conf > /dev/null 2>&1 - docker exec -it fail2ban fail2ban-client reload > /dev/null 2>&1 - docker_name="fail2ban" - check_docker_app - echo -e "SSH防禦程序$check_docker" - echo "fail2ban是一個SSH防止暴力破解工具" - echo "官網介紹:${gh_proxy}github.com/fail2ban/fail2ban" - echo "------------------------" - echo "1. 安裝防禦程序" - echo "------------------------" - echo "2. 查看SSH攔截記錄" - echo "3. 日誌實時監控" - echo "------------------------" - echo "9. 卸載防禦程序" - echo "------------------------" - echo "0. 返回上一級選單" - echo "------------------------" - read -e -p "請輸入你的選擇:" sub_choice - case $sub_choice in - 1) - install_docker - f2b_install_sshd - - cd ~ - f2b_status - break_end - ;; - 2) - echo "------------------------" - f2b_sshd - echo "------------------------" - break_end - ;; - 3) - tail -f /path/to/fail2ban/config/log/fail2ban/fail2ban.log - break - ;; - 9) - docker rm -f fail2ban - rm -rf /path/to/fail2ban - echo "Fail2Ban防禦程序已卸載" - ;; - *) - break - ;; - esac - fi - done + fail2ban_panel ;; @@ -11853,11 +14392,17 @@ EOF ;; + 39) + clear + linux_fav + ;; + 41) clear send_stats "留言板" - echo "科技lion留言板已遷移至官方社區!請在官方社區進行留言噢!" - echo "https://bbs.kejilion.pro/" + echo "訪問科技lion官方留言板,您對腳本有任何想法歡迎留言交流!" + echo "https://board.kejilion.pro" + echo "公共密碼: kejilion.sh" ;; 66) @@ -11867,16 +14412,18 @@ EOF echo "一條龍系統調優" echo "------------------------------------------------" echo "將對以下內容進行操作與優化" - echo "1. 更新系統到最新" + echo "1. 優化系統更新源,更新系統到最新" echo "2. 清理系統垃圾文件" echo -e "3. 設置虛擬內存${gl_huang}1G${gl_bai}" echo -e "4. 設置SSH端口號為${gl_huang}5522${gl_bai}" - echo -e "5. 開放所有端口" - echo -e "6. 開啟${gl_huang}BBR${gl_bai}加速" - echo -e "7. 設置時區到${gl_huang}上海${gl_bai}" - echo -e "8. 自動優化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 國內: 223.5.5.5${gl_bai}" - echo -e "9. 安裝基礎工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" - echo -e "10. Linux系統內核參數優化切換到${gl_huang}均衡優化模式${gl_bai}" + echo -e "5. 啟動fail2ban防禦SSH暴力破解" + echo -e "6. 開放所有端口" + echo -e "7. 開啟${gl_huang}BBR${gl_bai}加速" + echo -e "8. 設置時區到${gl_huang}上海${gl_bai}" + echo -e "9. 自動優化DNS地址${gl_huang}海外: 1.1.1.1 8.8.8.8 國內: 223.5.5.5${gl_bai}" + echo -e "10. 設置網絡為${gl_huang}ipv4優先${gl_bai}" + echo -e "11. 安裝基礎工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "12. Linux系統內核參數優化切換到${gl_huang}均衡優化模式${gl_bai}" echo "------------------------------------------------" read -e -p "確定一鍵保養嗎? (Y/N):" choice @@ -11885,58 +14432,54 @@ EOF clear send_stats "一條龍調優啟動" echo "------------------------------------------------" + switch_mirror false false linux_update - echo -e "[${gl_lv}OK${gl_bai}] 1/10. 更新系統到最新" + echo -e "[${gl_lv}OK${gl_bai}] 1/12. 更新系統到最新" echo "------------------------------------------------" linux_clean - echo -e "[${gl_lv}OK${gl_bai}] 2/10. 清理系統垃圾文件" + echo -e "[${gl_lv}OK${gl_bai}] 2/12. 清理系統垃圾文件" echo "------------------------------------------------" add_swap 1024 - echo -e "[${gl_lv}OK${gl_bai}] 3/10. 設置虛擬內存${gl_huang}1G${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 3/12. 設置虛擬內存${gl_huang}1G${gl_bai}" echo "------------------------------------------------" local new_port=5522 new_ssh_port - echo -e "[${gl_lv}OK${gl_bai}] 4/10. 設置SSH端口號為${gl_huang}5522${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 4/12. 設置SSH端口號為${gl_huang}5522${gl_bai}" echo "------------------------------------------------" - echo -e "[${gl_lv}OK${gl_bai}] 5/10. 開放所有端口" + f2b_install_sshd + cd ~ + f2b_status + echo -e "[${gl_lv}OK${gl_bai}] 5/12. 啟動fail2ban防禦SSH暴力破解" + + echo "------------------------------------------------" + echo -e "[${gl_lv}OK${gl_bai}] 6/12. 開放所有端口" echo "------------------------------------------------" bbr_on - echo -e "[${gl_lv}OK${gl_bai}] 6/10. 開啟${gl_huang}BBR${gl_bai}加速" + echo -e "[${gl_lv}OK${gl_bai}] 7/12. 開啟${gl_huang}BBR${gl_bai}加速" echo "------------------------------------------------" set_timedate Asia/Shanghai - echo -e "[${gl_lv}OK${gl_bai}] 7/10. 設置時區到${gl_huang}上海${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 8/12. 設置時區到${gl_huang}上海${gl_bai}" echo "------------------------------------------------" - local country=$(curl -s ipinfo.io/country) - if [ "$country" = "CN" ]; then - local dns1_ipv4="223.5.5.5" - local dns2_ipv4="183.60.83.19" - local dns1_ipv6="2400:3200::1" - local dns2_ipv6="2400:da00::6666" - else - local dns1_ipv4="1.1.1.1" - local dns2_ipv4="8.8.8.8" - local dns1_ipv6="2606:4700:4700::1111" - local dns2_ipv6="2001:4860:4860::8888" - fi - - set_dns - echo -e "[${gl_lv}OK${gl_bai}] 8/10. 自動優化DNS地址${gl_huang}${gl_bai}" + auto_optimize_dns + echo -e "[${gl_lv}OK${gl_bai}] 9/12. 自動優化DNS地址${gl_huang}${gl_bai}" + echo "------------------------------------------------" + prefer_ipv4 + echo -e "[${gl_lv}OK${gl_bai}] 10/12. 設置網絡為${gl_huang}ipv4優先${gl_bai}}" echo "------------------------------------------------" install_docker install wget sudo tar unzip socat btop nano vim - echo -e "[${gl_lv}OK${gl_bai}] 9/10. 安裝基礎工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" + echo -e "[${gl_lv}OK${gl_bai}] 11/12. 安裝基礎工具${gl_huang}docker wget sudo tar unzip socat btop nano vim${gl_bai}" echo "------------------------------------------------" - echo "------------------------------------------------" optimize_balanced - echo -e "[${gl_lv}OK${gl_bai}] 10/10. Linux系統內核參數優化" + echo -e "[${gl_lv}OK${gl_bai}] 12/12. Linux系統內核參數優化" echo -e "${gl_lv}一條龍系統調優已完成${gl_bai}" ;; @@ -11961,11 +14504,11 @@ EOF while true; do clear if grep -q '^ENABLE_STATS="true"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_lv}正在采集数据${gl_bai}" + local status_message="${gl_lv}正在採集數據${gl_bai}" elif grep -q '^ENABLE_STATS="false"' /usr/local/bin/k > /dev/null 2>&1; then - local status_message="${gl_hui}采集已关闭${gl_bai}" + local status_message="${gl_hui}採集已關閉${gl_bai}" else - local status_message="无法确定的状态" + local status_message="無法確定的狀態" fi echo "隱私與安全" @@ -12464,6 +15007,64 @@ echo "" +games_server_tools() { + + while true; do + clear + echo -e "遊戲開服腳本合集" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}1. ${gl_bai}幻獸帕魯開服腳本" + echo -e "${gl_kjlan}2. ${gl_bai}我的世界開服腳本" + echo -e "${gl_kjlan}------------------------" + echo -e "${gl_kjlan}0. ${gl_bai}返回主菜單" + echo -e "${gl_kjlan}------------------------${gl_bai}" + read -e -p "請輸入你的選擇:" sub_choice + + case $sub_choice in + + 1) send_stats "幻獸帕魯開服腳本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh + exit + ;; + 2) send_stats "我的世界開服腳本" ; cd ~ + curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/mc.sh ; chmod +x mc.sh ; ./mc.sh + exit + ;; + + 0) + kejilion + ;; + + *) + echo "無效的輸入!" + ;; + esac + break_end + + done + + +} + + + + + + + + + + + + + + + + + + + + kejilion_update() { @@ -12584,8 +15185,7 @@ echo -e "${gl_kjlan}12. ${gl_bai}後台工作區" echo -e "${gl_kjlan}13. ${gl_bai}系統工具" echo -e "${gl_kjlan}14. ${gl_bai}服務器集群控制" echo -e "${gl_kjlan}15. ${gl_bai}廣告專欄" -echo -e "${gl_kjlan}------------------------${gl_bai}" -echo -e "${gl_kjlan}p. ${gl_bai}幻獸帕魯開服腳本" +echo -e "${gl_kjlan}16. ${gl_bai}遊戲開服腳本合集" echo -e "${gl_kjlan}------------------------${gl_bai}" echo -e "${gl_kjlan}00. ${gl_bai}腳本更新" echo -e "${gl_kjlan}------------------------${gl_bai}" @@ -12594,7 +15194,7 @@ echo -e "${gl_kjlan}------------------------${gl_bai}" read -e -p "請輸入你的選擇:" choice case $choice in - 1) linux_ps ;; + 1) linux_info ;; 2) clear ; send_stats "系統更新" ; linux_update ;; 3) clear ; send_stats "系統清理" ; linux_clean ;; 4) linux_tools ;; @@ -12611,10 +15211,7 @@ case $choice in 13) linux_Settings ;; 14) linux_cluster ;; 15) kejilion_Affiliates ;; - p) send_stats "幻獸帕魯開服腳本" ; cd ~ - curl -sS -O ${gh_proxy}raw.githubusercontent.com/kejilion/sh/main/palworld.sh ; chmod +x palworld.sh ; ./palworld.sh - exit - ;; + 16) games_server_tools ;; 00) kejilion_update ;; 0) clear ; exit ;; *) echo "無效的輸入!" ;; @@ -12653,6 +15250,7 @@ echo "軟件狀態查看 k status sshd | k 狀態 sshd" echo "軟件開機啟動 k enable docker | k autostart docke | k 開機啟動 docker" echo "域名證書申請 k ssl" echo "域名證書到期查詢 k ssl ps" +echo "docker管理平面 k docker" echo "docker環境安裝 k docker install |k docker 安裝" echo "docker容器管理 k docker ps |k docker 容器" echo "docker鏡像管理 k docker img |k docker 鏡像" @@ -12661,13 +15259,17 @@ echo "LDNMP緩存清理 k web cache" echo "安裝WordPress k wp |k wordpress |k wp xxx.com" echo "安裝反向代理 k fd |k rp |k 反代 |k fd xxx.com" echo "安裝負載均衡 k loadbalance |k 負載均衡" +echo "安裝L4負載均衡 k stream |k L4負載均衡" echo "防火牆面板 k fhq |k 防火牆" echo "開放端口 k dkdk 8080 |k 打開端口 8080" echo "關閉端口 k gbdk 7800 |k 關閉端口 7800" echo "放行IP k fxip 127.0.0.0/8 |k 放行IP 127.0.0.0/8" echo "阻止IP k zzip 177.5.25.36 |k 阻止IP 177.5.25.36" - - +echo "命令收藏夾 k fav | k 命令收藏夾" +echo "應用市場管理 k app" +echo "應用編號快捷管理 k app 26 | k app 1panel | k app npm" +echo "fail2ban管理 k fail2ban | k f2b" +echo "顯示系統信息 k info" } @@ -12749,6 +15351,11 @@ else ldnmp_Proxy_backend ;; + + stream|L4负载均衡) + ldnmp_Proxy_backend_stream + ;; + swap) shift send_stats "快速設置虛擬內存" @@ -12799,6 +15406,10 @@ else iptables_panel ;; + 命令收藏夹|fav) + linux_fav + ;; + status|状态) shift send_stats "軟件狀態查看" @@ -12858,7 +15469,7 @@ else docker_image ;; *) - k_info + linux_docker ;; esac ;; @@ -12878,6 +15489,22 @@ else fi ;; + + app) + shift + send_stats "應用$@" + linux_panel "$@" + ;; + + + info) + linux_info + ;; + + fail2ban|f2b) + fail2ban_panel + ;; + *) k_info ;; diff --git a/upgrade_openssh9.8p1.sh b/upgrade_openssh9.8p1.sh index 78b5d7138..f56dc3d5a 100644 --- a/upgrade_openssh9.8p1.sh +++ b/upgrade_openssh9.8p1.sh @@ -70,6 +70,8 @@ install_openssh() { # 重启SSH服务 restart_ssh() { + mv /usr/bin/ssh /usr/bin/ssh.bak + ln -s /usr/local/bin/ssh /usr/bin/ssh case $OS in ubuntu|debian) systemctl restart ssh