如何用脚本监控服务器端口状态?

wen 实用脚本 1

本文目录导读:

如何用脚本监控服务器端口状态?

  1. 后台运行
  2. 或使用nohup

Bash脚本监控方案

基本端口检查脚本

#!/bin/bash
# 监控端口状态
check_port() {
    local host=$1
    local port=$2
    # 使用nc检查端口
    nc -z -w3 $host $port > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - Port $port is OPEN"
        return 0
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - Port $port is CLOSED"
        return 1
    fi
}
# 监控多个端口
ports=(80 443 22 3306)
for port in "${ports[@]}"; do
    check_port "localhost" $port
done

带告警功能的脚本

#!/bin/bash
# 配置
LOG_FILE="/var/log/port_monitor.log"
ALERT_EMAIL="admin@example.com"
MONITOR_PORTS=(80 443 3306)
MONITOR_HOST="127.0.0.1"
# 端口检查函数
check_port_status() {
    local host=$1
    local port=$2
    # 使用timeout和bash内置功能
    timeout 2 bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "UP"
    else
        echo "DOWN"
    fi
}
# 主监控循环
while true; do
    for port in "${MONITOR_PORTS[@]}"; do
        status=$(check_port_status $MONITOR_HOST $port)
        timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        # 记录日志
        echo "$timestamp - Port $port: $status" >> $LOG_FILE
        # 端口关闭时发送告警
        if [ "$status" = "DOWN" ]; then
            echo "Alert: Port $port is DOWN on $MONITOR_HOST at $timestamp" | \
                mail -s "Port Monitor Alert" $ALERT_EMAIL
        fi
    done
    # 每60秒检查一次
    sleep 60
done

Python脚本方案

使用socket模块

#!/usr/bin/env python3
import socket
import time
import logging
from datetime import datetime
class PortMonitor:
    def __init__(self, host='localhost', ports=None, timeout=5):
        self.host = host
        self.ports = ports or [80, 443, 22]
        self.timeout = timeout
        self.setup_logging()
    def setup_logging(self):
        logging.basicConfig(
            filename='port_monitor.log',
            level=logging.INFO,
            format='%(asctime)s - %(message)s'
        )
    def check_port(self, port):
        """检查单个端口状态"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(self.timeout)
        try:
            result = sock.connect_ex((self.host, port))
            sock.close()
            return result == 0
        except socket.error:
            return False
    def monitor_ports(self, interval=60):
        """持续监控端口"""
        while True:
            for port in self.ports:
                is_open = self.check_port(port)
                status = "OPEN" if is_open else "CLOSED"
                message = f"Port {port}: {status}"
                print(f"{datetime.now()} - {message}")
                logging.info(f"Port {port}: {status}")
                # 端口关闭时发送告警
                if not is_open:
                    self.send_alert(port)
            time.sleep(interval)
    def send_alert(self, port):
        """发送告警(示例使用打印)"""
        print(f"⚠️ ALERT: Port {port} is DOWN!")
        # 实际可以发送邮件、短信等
# 使用示例
if __name__ == "__main__":
    monitor = PortMonitor(
        host='localhost',
        ports=[80, 443, 22, 3306],
        timeout=3
    )
    monitor.monitor_ports(interval=30)  # 每30秒检查一次

完整的运维监控脚本

#!/bin/bash
# 端口监控脚本 - 生产环境使用
CONFIG_FILE="/etc/port_monitor.conf"
LOG_DIR="/var/log/port_monitor"
ALERT_SCRIPT="/usr/local/bin/send_alert.sh"
# 创建日志目录
mkdir -p $LOG_DIR
# 加载配置文件
if [ -f "$CONFIG_FILE" ]; then
    source $CONFIG_FILE
else
    # 默认配置
    MONITOR_HOST="localhost"
    MONITOR_PORTS="80,443,22,3306,6379"
    CHECK_INTERVAL=30
    ALERT_EMAIL="ops@company.com"
fi
# 检查端口函数
check_port() {
    host=$1
    port=$2
    # 多种检测方式
    # 方法1: nc
    nc -z -w2 $host $port 2>/dev/null
    if [ $? -eq 0 ]; then
        return 0
    fi
    # 方法2: telnet
    timeout 2 telnet $host $port 2>&1 | grep -q "Connected"
    if [ $? -eq 0 ]; then
        return 0
    fi
    # 方法3: /dev/tcp
    timeout 2 bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null
    return $?
}
# 记录日志
write_log() {
    local host=$1
    local port=$2
    local status=$3
    local log_file="$LOG_DIR/port_${port}.log"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $host:$port - $status" >> $log_file
}
# 发送告警
send_alert() {
    local host=$1
    local port=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    # 发送邮件
    echo "Server: $host" > /tmp/alert.txt
    echo "Port: $port" >> /tmp/alert.txt
    echo "Time: $timestamp" >> /tmp/alert.txt
    echo "Status: DOWN" >> /tmp/alert.txt
    mail -s "[ALERT] Port $port is DOWN on $host" $ALERT_EMAIL < /tmp/alert.txt
    # 或调用外部脚本
    if [ -x "$ALERT_SCRIPT" ]; then
        $ALERT_SCRIPT $host $port
    fi
}
# 主循环
main() {
    # 分割端口列表
    IFS=',' read -ra PORTS <<< "$MONITOR_PORTS"
    while true; do
        for port in "${PORTS[@]}"; do
            # 去除空格
            port=$(echo $port | tr -d ' ')
            if check_port $MONITOR_HOST $port; then
                write_log $MONITOR_HOST $port "UP"
            else
                write_log $MONITOR_HOST $port "DOWN"
                send_alert $MONITOR_HOST $port
            fi
        done
        sleep $CHECK_INTERVAL
    done
}
# 启动监控
main

配置文件和systemd服务

配置文件 /etc/port_monitor.conf

# 端口监控配置
MONITOR_HOST="localhost"
MONITOR_PORTS="80,443,22,3306"
CHECK_INTERVAL=30
ALERT_EMAIL="admin@company.com"

Systemd服务文件 /etc/systemd/system/port-monitor.service

[Unit]
Description=Port Monitor Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/port_monitor.sh
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target

使用说明

  1. 基本使用
    # 赋予执行权限
    chmod +x port_monitor.sh

后台运行

nohup ./port_monitor.sh &

或使用nohup

nohup python3 port_monitor.py &


2. **部署为服务**
```bash
# 复制脚本
cp port_monitor.sh /usr/local/bin/
chmod +x /usr/local/bin/port_monitor.sh
# 启用服务
systemctl daemon-reload
systemctl enable port-monitor
systemctl start port-monitor

建议

  1. 错误处理:添加重试机制和错误恢复
  2. 资源控制:设置合理的检查间隔,避免过度消耗资源
  3. 日志管理:配置日志轮转,防止磁盘空间占满
  4. 告警阈值:设置连续失败次数触发告警,避免误报
  5. 监控指标:除了端口状态,也可监控响应时间

需要根据具体环境和需求选择合适的方案,对于生产环境,建议结合专业的监控系统(如Prometheus、Zabbix)使用。

抱歉,评论功能暂时关闭!