From 5f59066c5d2bf029944ca19d6c788a4c8decc88d Mon Sep 17 00:00:00 2001 From: baichal <154722332+baichal@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:58:22 +0800 Subject: [PATCH] Create Socat --- Socat | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 Socat diff --git a/Socat b/Socat new file mode 100644 index 0000000..0feac23 --- /dev/null +++ b/Socat @@ -0,0 +1,268 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# ==================================================== +# 系统要求: CentOS 6+、Debian 7+、Ubuntu 14+ +# 描述: Socat 一键安装管理脚本 +# 版本: 2.8 +# 作者:白茶 +# ==================================================== + +Green="\033[32m" +Font="\033[0m" +Blue="\033[34m" +Red="\033[31m" +Yellow="\033[33m" + +# 清屏函数 +clear_screen() { + clear +} + +# 按键继续函数 +press_any_key() { + echo + read -n 1 -s -r -p "按任意键继续..." + clear_screen +} + +# 检查是否为root用户 +check_root(){ + if [[ $EUID -ne 0 ]]; then + echo "错误:此脚本必须以root身份运行!" 1>&2 + exit 1 + fi +} + +# 检查系统类型 +check_sys(){ + if [[ -f /etc/redhat-release ]]; then + OS="CentOS" + elif cat /etc/issue | grep -q -E -i "debian"; then + OS="Debian" + elif cat /etc/issue | grep -q -E -i "ubuntu"; then + OS="Ubuntu" + elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then + OS="CentOS" + else + echo "不支持的操作系统!" + exit 1 + fi +} + +# 获取本机IP(使用多个备选服务) +get_ip(){ + local ip_services=("http://ipv4.icanhazip.com" "http://api.ipify.org" "http://ifconfig.me") + for service in "${ip_services[@]}"; do + ip=$(curl -s -m 10 "$service") + if [[ -n "$ip" ]]; then + break + fi + done + + if [[ -z "$ip" ]]; then + ip=$(ip addr | grep 'inet ' | grep -v 127.0.0.1 | head -n1 | awk '{print $2}' | cut -d'/' -f1) + fi + + if [[ -z "$ip" ]]; then + echo -e "${Red}无法获取服务器IP地址${Font}" + ip="未知" + fi +} + +# 安装Socat(只在需要时执行) +install_socat(){ + if [ ! -s /usr/bin/socat ]; then + echo -e "${Green}正在安装 Socat...${Font}" + if [ "${OS}" == "CentOS" ]; then + yum install -y socat + else + apt-get -y update + apt-get install -y socat + fi + if [ -s /usr/bin/socat ]; then + echo -e "${Green}Socat 安装完成!${Font}" + else + echo -e "${Red}Socat 安装失败,请检查网络连接和系统设置。${Font}" + exit 1 + fi + fi +} + +# 配置Socat +config_socat(){ + echo -e "${Green}请输入Socat配置信息!${Font}" + read -p "请输入本地端口: " port1 + read -p "请输入远程端口: " port2 + read -p "请输入远程IP: " socatip +} + +# 启动Socat +start_socat(){ + echo -e "${Green}正在配置Socat...${Font}" + nohup socat TCP4-LISTEN:${port1},reuseaddr,fork TCP4:${socatip}:${port2} >> /root/socat.log 2>&1 & + + # 检查是否成功启动 + sleep 2 + if pgrep -f "socat.*LISTEN:${port1}.*TCP4:${socatip}:${port2}" > /dev/null; then + echo -e "${Green}Socat配置成功!${Font}" + echo -e "${Blue}本地端口: ${port1}${Font}" + echo -e "${Blue}远程端口: ${port2}${Font}" + echo -e "${Blue}远程IP: ${socatip}${Font}" + get_ip + echo -e "${Blue}本地服务器IP: ${ip}${Font}" + + # 添加到开机自启 + add_to_startup + else + echo -e "${Red}Socat启动失败,请检查配置和系统设置。${Font}" + fi +} + +# 添加到开机自启 +add_to_startup() { + rc_local="/etc/rc.local" + if [ ! -f "$rc_local" ]; then + echo '#!/bin/bash' > "$rc_local" + fi + + startup_cmd="nohup socat TCP4-LISTEN:${port1},reuseaddr,fork TCP4:${socatip}:${port2} >> /root/socat.log 2>&1 &" + if ! grep -q "$startup_cmd" "$rc_local"; then + echo "$startup_cmd" >> "$rc_local" + chmod +x "$rc_local" + echo -e "${Green}已添加到开机自启动${Font}" + else + echo -e "${Yellow}该转发已在开机自启动列表中${Font}" + fi +} + +# 显示和删除转发 +view_delete_forward() { + local forwards=$(ps aux | grep socat | grep -v grep | grep -v "socat.sh") + if [ -z "$forwards" ]; then + echo -e "${Red}当前没有活动的转发。${Font}" + return + fi + + echo -e "${Green}当前转发列表:${Font}" + local i=1 + declare -A unique_forwards + + while read -r line; do + local pid=$(echo $line | awk '{print $2}') + local config=$(echo $line | awk -F'socat ' '{print $2}') + local listen_port=$(echo $config | awk -F'LISTEN:' '{print $2}' | cut -d',' -f1) + local remote_info=$(echo $config | awk -F'TCP4:' '{print $2}') + local remote_ip=$(echo $remote_info | cut -d: -f1) + local remote_port=$(echo $remote_info | cut -d: -f2) + + local key="${listen_port}:${remote_ip}:${remote_port}" + if [[ -z ${unique_forwards[$key]} ]]; then + unique_forwards[$key]="$i. $ip:$listen_port --> $remote_ip:$remote_port (PID: $pid)" + ((i++)) + fi + done <<< "$forwards" + + for forward in "${unique_forwards[@]}"; do + echo "$forward" + done + + read -p "请输入要删除的转发编号(多个编号用空格分隔,直接回车取消): " numbers + if [ -n "$numbers" ]; then + for num in $numbers; do + local selected_forward="" + for forward in "${unique_forwards[@]}"; do + if [[ $forward == $num.* ]]; then + selected_forward=$forward + break + fi + done + + if [ -n "$selected_forward" ]; then + local listen_port=$(echo $selected_forward | awk -F':' '{print $2}' | awk '{print $1}') + local pids=$(pgrep -f "socat.*LISTEN:${listen_port}") + for pid in $pids; do + kill -9 $pid + echo -e "${Green}已删除转发: PID $pid${Font}" + done + remove_from_startup $listen_port + fi + done + fi +} + +# 从开机自启动中移除 +remove_from_startup() { + local listen_port=$1 + rc_local="/etc/rc.local" + if [ -f "$rc_local" ]; then + sed -i "/socat.*LISTEN:${listen_port}/d" "$rc_local" + echo -e "${Green}已从开机自启动中移除端口 ${listen_port} 的转发${Font}" + fi +} + +# 强制终止所有Socat进程 +kill_all_socat() { + echo -e "${Yellow}正在终止所有 Socat 进程...${Font}" + pkill -9 socat + sleep 2 + if pgrep -f socat > /dev/null; then + echo -e "${Red}警告:某些 Socat 进程可能仍在运行。请考虑手动检查。${Font}" + else + echo -e "${Green}所有 Socat 进程已成功终止。${Font}" + fi + # 清理开机自启动脚本 + sed -i '/socat TCP4-LISTEN/d' /etc/rc.local + echo -e "${Green}已从开机自启动中移除所有 Socat 转发${Font}" +} + +# 显示菜单 +show_menu() { + echo -e "${Green}========= Socat 管理脚本 ==========${Font}" + echo "1. 添加新转发" + echo "2. 查看或删除转发" + echo "3. 强制终止所有 Socat 进程" + echo "4. 退出脚本" + echo -e "${Green}=====================================${Font}" +} + +# 主程序 +main() { + check_root + check_sys + install_socat + clear_screen + + while true; do + show_menu + read -p "请输入选项 [1-4]: " choice + clear_screen + case $choice in + 1) + config_socat + start_socat + press_any_key + ;; + 2) + view_delete_forward + press_any_key + ;; + 3) + kill_all_socat + press_any_key + ;; + 4) + echo -e "${Green}感谢使用,再见!${Font}" + exit 0 + ;; + *) + echo -e "${Red}无效选项,请重新选择${Font}" + press_any_key + ;; + esac + done +} + +# 执行主程序 +main