#!/bin/bash # ========================================================= # 單獨修復:編譯 OpenSSL 1.1.1w + 安裝 Ruby 2.7.6 # 在家目錄執行:bash -l fix_ruby.sh # ========================================================= OPENSSL_DIR="/opt/openssl" CPU_CORES=$(nproc) LOG_FILE="$HOME/fix_ruby_$(date +%Y%m%d_%H%M%S).log" # 同時輸出到終端機和 log 檔 exec > >(tee -a "$LOG_FILE") 2>&1 echo "==========================================================" echo " 開始修復 OpenSSL + Ruby 2.7.6" echo " Log 檔案:$LOG_FILE" echo " 時間:$(date)" echo " CPU 核心數:$CPU_CORES" echo " 系統:$(uname -a)" echo "==========================================================" # --- 載入 RVM --- source "/etc/profile.d/rvm.sh" if ! command -v rvm &>/dev/null; then echo "❌ RVM 載入失敗,請確認 RVM 已安裝" exit 1 fi echo "✅ RVM 載入成功:$(rvm --version | head -1)" # --- 編譯 OpenSSL 1.1.1w --- echo "" echo "--- [1/3] 編譯 OpenSSL 1.1.1w ---" echo " 時間:$(date)" if [[ -f "$OPENSSL_DIR/lib/libssl.so" ]] || [[ -f "$OPENSSL_DIR/lib/libssl.a" ]]; then echo " ✅ OpenSSL 已存在,跳過編譯" echo " 現有版本:$(ls -la $OPENSSL_DIR/lib/libssl* 2>/dev/null)" else echo " > /opt/openssl 不存在,開始重新編譯" sudo rm -rf "$OPENSSL_DIR" cd /tmp rm -rf openssl-1.1.1w.tar.gz openssl-1.1.1w echo " > 下載中..." wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz \ --no-check-certificate -q -O openssl-1.1.1w.tar.gz if [[ $? -ne 0 ]]; then echo "❌ 下載失敗" exit 1 fi echo " ✅ 下載完成:$(ls -lh /tmp/openssl-1.1.1w.tar.gz)" echo " > 解壓縮..." tar xzf openssl-1.1.1w.tar.gz cd openssl-1.1.1w echo " > 設定..." ./config no-ssl2 no-ssl3 zlib-dynamic -fPIC shared \ --prefix="$OPENSSL_DIR" 2>&1 | tail -5 if [[ $? -ne 0 ]]; then echo "❌ config 失敗" exit 1 fi echo " > make depend..." make depend -j"$CPU_CORES" echo " > 編譯中(需要數分鐘)..." make -j"$CPU_CORES" MAKE_EXIT=$? if [[ $MAKE_EXIT -ne 0 ]]; then echo "⚠️ make 有部分錯誤(exit=$MAKE_EXIT),但可能只是 fuzz/apps,繼續嘗試安裝..." fi echo " > 安裝..." sudo make install_sw sudo make install_ssldirs # 建立憑證連結 sudo rm -rf "$OPENSSL_DIR/ssl/certs" sudo ln -sf /etc/ssl/certs/ "$OPENSSL_DIR/ssl/." # 驗證 echo " > 驗證安裝結果:" ls -la "$OPENSSL_DIR/lib/" 2>/dev/null | grep -E "libssl|libcrypto" if [[ ! -f "$OPENSSL_DIR/lib/libssl.so" ]] && [[ ! -f "$OPENSSL_DIR/lib/libssl.a" ]]; then echo "❌ OpenSSL 編譯失敗!libssl 不存在" exit 1 fi echo "✅ OpenSSL 安裝成功" fi # --- 安裝 Ruby 2.7.6 --- echo "" echo "--- [2/3] 安裝 Ruby 2.7.6 ---" echo " 時間:$(date)" echo " 使用 OpenSSL:$OPENSSL_DIR" echo " libssl.so:$(ls -la $OPENSSL_DIR/lib/libssl.so 2>/dev/null || echo '不存在')" echo " libssl.a :$(ls -la $OPENSSL_DIR/lib/libssl.a 2>/dev/null || echo '不存在')" # 移除殘留 if rvm list | grep -q "2.7.6"; then echo " > 移除舊版..." rvm remove "2.7.6" --force 2>/dev/null || true fi # 設定編譯環境變數 export LD_LIBRARY_PATH="$OPENSSL_DIR/lib" export CPPFLAGS="-I$OPENSSL_DIR/include" export LDFLAGS="-L$OPENSSL_DIR/lib" export CFLAGS="-Wno-error=incompatible-pointer-types -Wno-implicit-function-declaration -Wno-discarded-qualifiers" echo " > 環境變數:" echo " LD_LIBRARY_PATH=$LD_LIBRARY_PATH" echo " CPPFLAGS=$CPPFLAGS" echo " LDFLAGS=$LDFLAGS" echo " CFLAGS=$CFLAGS" echo " > 開始編譯 Ruby 2.7.6(需要 10~20 分鐘)..." rvm install "2.7.6" \ --verify-downloads 1 \ --with-openssl-dir="$OPENSSL_DIR" \ --with-opt-dir="$OPENSSL_DIR" \ -- \ --with-jemalloc RVM_EXIT=$? echo " > rvm install 結束,exit code:$RVM_EXIT" # 如果失敗,自動印出最後的 make log if [[ $RVM_EXIT -ne 0 ]]; then MAKE_LOG=$(find ~/.rvm/log -name "make.log" 2>/dev/null | sort | tail -1) if [[ -f "$MAKE_LOG" ]]; then echo "" echo "--- make.log 最後 40 行 ---" tail -40 "$MAKE_LOG" echo "" echo "--- make.log 錯誤行 ---" grep -i "error:" "$MAKE_LOG" | head -20 fi CONF_LOG=$(find ~/.rvm/log -name "configure.log" 2>/dev/null | sort | tail -1) if [[ -f "$CONF_LOG" ]]; then echo "" echo "--- configure.log 最後 20 行 ---" tail -20 "$CONF_LOG" fi echo "❌ Ruby 安裝失敗" exit 1 fi # 清除編譯環境變數 unset LD_LIBRARY_PATH CPPFLAGS LDFLAGS CFLAGS rvm --default use "2.7.6" # --- 安裝 Gems --- echo "" echo "--- [3/3] 安裝 Gems ---" echo " 時間:$(date)" gem install bundler -v 2.1.4 gem install zip gem install nokogiri -v 1.8.5 # --- 最終驗證 --- echo "" echo "==========================================================" echo " 最終驗證" echo " 時間:$(date)" echo "==========================================================" source "/etc/profile.d/rvm.sh" rvm use "2.7.6" RUBY_VER=$(ruby -v 2>/dev/null || echo "") OPENSSL_VER=$(ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' 2>/dev/null || echo "") GEM_LIST=$(gem list | grep -E 'bundler|nokogiri|zip' | tr '\n' ' ') if [[ "$RUBY_VER" == *"2.7.6"* ]] && [[ -n "$OPENSSL_VER" ]]; then echo "✅ Ruby : $RUBY_VER" echo "✅ OpenSSL : $OPENSSL_VER" echo "✅ Gems : $GEM_LIST" echo "==========================================================" echo " 全部安裝成功!" echo " Log 已儲存至:$LOG_FILE" echo "==========================================================" else echo "❌ Ruby : ${RUBY_VER:-未安裝}" echo "❌ OpenSSL : ${OPENSSL_VER:-無法載入}" echo "" echo "請檢查 log 檔案:$LOG_FILE" echo "==========================================================" exit 1 fi