mesg 命令用于控制终端是否允许接收其他用户通过write或talk命令发送的消息。在多用户Linux系统中,这个命令可以保护终端不被其他用户的消息干扰,提高工作专注度。
write和talk命令直接向其他用户的终端发送消息。mesg命令用于控制是否允许接收这类消息。
# 基本格式
mesg [选项] [y|n]
# 常用格式
mesg # 显示当前状态
mesg y # 允许接收消息
mesg n # 禁止接收消息
mesg -V # 显示版本信息
mesg -h # 显示帮助信息
mesg 是GNU coreutils的一部分,几乎所有Linux发行版都预装了:
# 1. 检查是否已安装
which mesg
mesg --version
# 输出示例:mesg (GNU coreutils) 8.30
# 2. 如果未安装,安装coreutils
# 实际上mesg几乎总是已安装,但如果需要:
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install coreutils
# RHEL/CentOS
sudo yum install coreutils
# 或
sudo dnf install coreutils
# 3. 查看coreutils版本
ls --version | head -1
# 或
cp --version | head -1
# 4. 从源码编译coreutils(不推荐)
wget https://ftp.gnu.org/gnu/coreutils/coreutils-8.32.tar.xz
tar -xf coreutils-8.32.tar.xz
cd coreutils-8.32
./configure
make
sudo make install
# 5. 相关工具包
# 除了coreutils,这些工具也可能包含mesg:
# util-linux: 包含write, wall, mesg等
# bsdutils: BSD工具版本
# 6. 验证安装
mesg
# 应该显示:is y 或 is n
使用mesg进行基本的消息控制:
# 1. 查看当前消息状态
mesg
# 输出:is y (允许接收消息)
# 或:is n (禁止接收消息)
# 2. 允许接收消息
mesg y
# 或
mesg yes
# 输出:is y
# 3. 禁止接收消息
mesg n
# 或
mesg no
# 输出:is n
# 4. 在脚本中检查状态
if mesg | grep -q "is y"; then
echo "消息接收已启用"
else
echo "消息接收已禁用"
fi
# 5. 切换状态
# 如果当前是y,切换到n;如果是n,切换到y
mesg $(mesg | awk '{print $2 == "y" ? "n" : "y"}')
# 6. 显示详细信息
mesg -v
# 输出更详细的信息
# 7. 在多个终端中设置
# 为当前tty设置
mesg y
# 查看当前tty
tty
# 输出:/dev/pts/0
# 8. 检查其他用户的终端状态
# 首先查看哪些用户已登录
who
# 输出示例:
# alice pts/0 2023-10-01 10:00 (192.168.1.100)
# bob pts/1 2023-10-01 10:05 (192.168.1.101)
# 检查Alice的终端是否允许消息
sudo -u alice mesg
# 注意:需要权限或Alice的登录shell
# 9. 在.bashrc中设置默认值
# 添加到~/.bashrc
echo "mesg n 2>/dev/null || true" >> ~/.bashrc
# 这样每次登录时自动禁用消息
# 10. 临时测试消息
# 终端1:启动消息监听
mesg y
# 等待消息
# 终端2:向终端1发送消息
# 首先查看终端1的tty
# 在终端1中运行:tty
# 假设终端1是/dev/pts/0
write alice pts/0
# 然后输入消息,按Ctrl+D发送
# 11. 批量设置用户
# 为系统所有用户禁用消息(需要root)
for user in $(getent passwd | cut -d: -f1); do
sudo -u "$user" mesg n 2>/dev/null || true
done
# 12. 检查系统范围的消息策略
# 查看/etc/profile或/etc/bash.bashrc中是否有全局设置
grep -r "mesg" /etc/profile /etc/bash.bashrc /etc/bashrc 2>/dev/null
# 13. 消息状态与tty权限的关系
# mesg实际上修改了tty设备的写权限
ls -l $(tty)
# 启用消息时:crw--w----
# 禁用消息时:crw-------
# 14. 直接修改tty权限(不推荐)
# 启用消息
chmod g+w $(tty)
# 禁用消息
chmod g-w $(tty)
# 15. 在远程会话中保持设置
# SSH连接时,mesg设置不会自动继承
# 可以在~/.bashrc中添加:
if [ -t 0 ]; then
mesg n
fi
# 16. 调试消息问题
# 详细模式查看发生了什么
mesg -v y
# 可能显示:change mode of /dev/pts/0 to 0620
# 17. 检查coreutils版本
mesg --version
# 输出:mesg (GNU coreutils) 8.30
# 18. 获取帮助
mesg --help
# 显示使用帮助
# 19. 在脚本中安全使用
# 总是检查命令是否成功
if mesg n; then
echo "消息已禁用"
else
echo "无法禁用消息" >&2
fi
# 20. 与其他命令结合
# 在运行重要任务时禁用消息
mesg n
# 运行重要脚本
./important_script.sh
# 完成后恢复
mesg y
配合write和talk命令进行用户间通信:
#!/bin/bash
# write和talk命令使用示例
# 1. 查看在线用户
who
# 输出示例:
# alice pts/0 2023-10-01 10:00 (192.168.1.100)
# bob pts/1 2023-10-01 10:05 (192.168.1.101)
# charlie pts/2 2023-10-01 10:10 (192.168.1.102)
# 2. 检查用户的消息状态
check_user_mesg() {
local user=$1
local tty=$2
echo "检查用户 $user 在 $tty 的消息状态:"
# 尝试检查(需要权限)
sudo -u "$user" mesg 2>/dev/null || echo "无法检查"
}
# 3. 使用write发送消息
send_message_write() {
local target_user=$1
local target_tty=$2
local message=$3
echo "向 $target_user ($target_tty) 发送消息: $message"
# 方法1:直接通过管道
echo "$message" | write "$target_user" "$target_tty"
# 方法2:交互式发送
# write "$target_user" "$target_tty"
# 然后输入消息,按Ctrl+D结束
}
# 4. 使用talk进行实时聊天
start_talk() {
local target_user=$1
local target_host=${2:-localhost}
echo "启动与 $target_user@$target_host 的talk会话"
# 启动talk客户端
talk "$target_user@$target_host"
# 注意:talk需要双方都运行talkd服务
# 检查talkd服务
systemctl status inetd 2>/dev/null || systemctl status xinetd 2>/dev/null
}
# 5. 广播消息给所有用户
broadcast_message() {
local message=$1
echo "广播消息: $message"
# 使用wall命令
wall <<< "$message"
# 或使用write给每个用户
who | while read user tty rest; do
echo "$message" | write "$user" "$tty" 2>/dev/null
done
}
# 6. 消息发送工具函数
message_tool() {
echo "=== 用户消息工具 ==="
# 显示在线用户
echo "在线用户:"
who
echo ""
echo "请选择操作:"
echo "1. 发送write消息"
echo "2. 启动talk会话"
echo "3. 广播消息"
echo "4. 检查消息状态"
echo "5. 退出"
echo ""
read -p "选择: " choice
case $choice in
1)
read -p "目标用户名: " user
read -p "目标tty(如pts/0): " tty
read -p "消息内容: " message
send_message_write "$user" "$tty" "$message"
;;
2)
read -p "目标用户名: " user
read -p "目标主机(默认localhost): " host
start_talk "$user" "${host:-localhost}"
;;
3)
read -p "广播消息: " message
broadcast_message "$message"
;;
4)
who | while read user tty rest; do
check_user_mesg "$user" "$tty"
done
;;
5)
echo "退出"
exit 0
;;
*)
echo "无效选择"
;;
esac
}
# 7. 自动消息系统
auto_message_system() {
# 监控新登录用户并发送欢迎消息
while true; do
# 获取当前登录用户
current_users=$(who | awk '{print $1" "$2}')
# 检查是否有新用户
for user_tty in $current_users; do
user=$(echo "$user_tty" | awk '{print $1}')
tty=$(echo "$user_tty" | awk '{print $2}')
# 检查是否已发送过欢迎消息
if [ ! -f "/tmp/welcomed_$user_$tty" ]; then
# 发送欢迎消息
echo "欢迎 $user! 登录时间: $(date)" | write "$user" "$tty" 2>/dev/null
# 标记已发送
touch "/tmp/welcomed_$user_$tty"
fi
done
sleep 60 # 每分钟检查一次
done
}
# 8. 消息日志系统
message_logging_system() {
LOG_DIR="/var/log/user_messages"
mkdir -p "$LOG_DIR"
# 监控所有write消息
while read -r line; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] $line" >> "$LOG_DIR/messages.log"
done
}
# 9. 安全消息系统
secure_message_system() {
# 只允许特定用户发送消息
ALLOWED_SENDERS=("admin" "operator")
ALLOWED_RECEIVERS=("alice" "bob" "charlie")
send_secure_message() {
local sender=$1
local receiver=$2
local message=$3
# 检查发送者权限
if [[ ! " ${ALLOWED_SENDERS[@]} " =~ " ${sender} " ]]; then
echo "错误: $sender 无权发送消息"
return 1
fi
# 检查接收者权限
if [[ ! " ${ALLOWED_RECEIVERS[@]} " =~ " ${receiver} " ]]; then
echo "错误: 不能向 $receiver 发送消息"
return 1
fi
# 发送消息
echo "$message" | write "$receiver"
}
}
# 10. 消息状态监控
monitor_message_status() {
echo "消息状态监控 - 更新于: $(date)"
echo "========================================"
who | while read user tty from date time; do
status=$(sudo -u "$user" mesg 2>/dev/null || echo "未知")
echo "$user ($tty): $status"
done
echo "========================================"
}
# 11. 批量消息操作
batch_message_operations() {
# 为所有用户启用消息
enable_all_messages() {
who | awk '{print $1}' | sort -u | while read user; do
sudo -u "$user" mesg y 2>/dev/null && echo "已为 $user 启用消息"
done
}
# 为所有用户禁用消息
disable_all_messages() {
who | awk '{print $1}' | sort -u | while read user; do
sudo -u "$user" mesg n 2>/dev/null && echo "已为 $user 禁用消息"
done
}
}
# 12. 消息系统测试
test_message_system() {
echo "测试消息系统..."
# 测试当前用户的消息功能
echo "1. 测试当前用户:"
mesg y
echo "状态: $(mesg)"
# 测试write功能
echo -e "\n2. 测试write功能:"
current_user=$(whoami)
current_tty=$(tty | cut -d/ -f3-)
echo "向自己发送测试消息..."
echo "测试消息 from $(date)" | write "$current_user" "$current_tty"
# 测试禁用功能
echo -e "\n3. 测试禁用功能:"
mesg n
echo "尝试发送消息到禁用状态..."
echo "此消息不应显示" | write "$current_user" "$current_tty" 2>/dev/null
# 恢复状态
mesg y
echo "测试完成"
}
# 13. 主菜单
main_menu() {
while true; do
clear
echo "=== 用户消息系统 ==="
echo ""
echo "1. 消息工具"
echo "2. 消息状态监控"
echo "3. 批量消息操作"
echo "4. 测试消息系统"
echo "5. 自动消息系统"
echo "6. 当前消息状态"
echo "0. 退出"
echo ""
read -p "选择: " choice
case $choice in
1) message_tool ;;
2) monitor_message_status ;;
3)
echo "1. 为所有用户启用消息"
echo "2. 为所有用户禁用消息"
read -p "选择: " batch_choice
case $batch_choice in
1) enable_all_messages ;;
2) disable_all_messages ;;
esac
;;
4) test_message_system ;;
5)
echo "启动自动消息系统 (Ctrl+C停止)"
auto_message_system
;;
6)
echo "当前消息状态: $(mesg)"
who
;;
0)
echo "退出"
exit 0
;;
*)
echo "无效选择"
;;
esac
echo ""
read -p "按回车键继续..."
done
}
# 运行主菜单
main_menu
mesg在系统管理和安全方面的应用:
#!/bin/bash
# 系统管理和安全配置
# 1. 系统范围的消息策略
system_wide_policy() {
echo "配置系统范围的消息策略..."
# 检查当前策略
echo "当前系统策略:"
grep -r "mesg" /etc/profile /etc/bash.bashrc /etc/bashrc /etc/skel 2>/dev/null || echo "无系统策略"
# 建议的系统策略
cat > /tmp/system_mesg_policy.txt << 'EOF'
# 系统消息策略建议
# =====================================
# 1. 生产服务器:默认禁用消息
# 在/etc/profile中添加:
# if [ -t 0 ]; then
# mesg n 2>/dev/null || true
# fi
# 2. 开发服务器:默认启用消息
# 在/etc/profile中添加:
# if [ -t 0 ]; then
# mesg y 2>/dev/null || true
# fi
# 3. 根据不同用户组设置不同策略
# 在/etc/profile中添加:
# if [ -t 0 ]; then
# if groups $USER | grep -q "developers"; then
# mesg y
# else
# mesg n
# fi
# fi
# 4. 根据时间设置策略
# 在/etc/profile中添加:
# if [ -t 0 ]; then
# hour=$(date +%H)
# if [ $hour -ge 9 ] && [ $hour -lt 18 ]; then
# mesg y # 工作时间启用
# else
# mesg n # 非工作时间禁用
# fi
# fi
EOF
echo "策略建议已保存到: /tmp/system_mesg_policy.txt"
}
# 2. 安全审计配置
security_audit_config() {
echo "配置消息安全审计..."
# 创建审计脚本
cat > /usr/local/bin/mesg_audit.sh << 'EOF'
#!/bin/bash
# 消息系统审计脚本
AUDIT_LOG="/var/log/mesg_audit.log"
log_event() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$AUDIT_LOG"
}
# 记录所有消息发送尝试
monitor_messages() {
# 监控/dev/pts设备
inotifywait -m -e modify /dev/pts/ 2>/dev/null | while read path action file; do
if [ -n "$file" ]; then
tty="/dev/pts/${file}"
user=$(stat -c "%U" "$tty" 2>/dev/null)
status=$(sudo -u "$user" mesg 2>/dev/null || echo "unknown")
log_event "TTY访问: $tty, 用户: $user, 消息状态: $status"
fi
done
}
# 定期检查消息状态
check_status() {
while true; do
who | while read user tty rest; do
status=$(sudo -u "$user" mesg 2>/dev/null || echo "unknown")
log_event "状态检查: $user ($tty) = $status"
done
sleep 300 # 每5分钟检查一次
done
}
# 运行审计
log_event "=== 消息审计开始 ==="
monitor_messages &
check_status &
EOF
chmod +x /usr/local/bin/mesg_audit.sh
echo "审计脚本已创建: /usr/local/bin/mesg_audit.sh"
}
# 3. 入侵检测集成
intrusion_detection() {
echo "配置入侵检测..."
cat > /etc/security/mesg_ids.rules << 'EOF'
# 消息系统入侵检测规则
# =====================================
# 规则1: 频繁消息发送
# 如果同一用户在60秒内发送超过10条消息,触发警报
RULE frequent_messages {
condition: $MSG_COUNT > 10 in 60s
action: alert("频繁消息发送: $USER")
}
# 规则2: 向多个用户广播
# 如果用户在短时间内向超过5个不同用户发送消息,触发警报
RULE broadcast_attack {
condition: $UNIQUE_RECEIVERS > 5 in 120s
action: alert("可疑广播: $USER")
}
# 规则3: 非工作时间活动
# 如果在非工作时间(22:00-06:00)发送消息,记录日志
RULE after_hours {
condition: $HOUR < 6 or $HOUR >= 22
action: log("非工作时间消息: $USER -> $RECEIVER")
}
# 规则4: 权限提升尝试
# 如果普通用户尝试向root发送消息,触发警报
RULE privilege_escalation {
condition: $RECEIVER == "root" and $USER != "root"
action: alert("权限提升尝试: $USER -> root")
}
EOF
echo "入侵检测规则已保存到: /etc/security/mesg_ids.rules"
}
# 4. 合规性检查
compliance_check() {
echo "运行合规性检查..."
cat > /tmp/mesg_compliance_check.sh << 'EOF'
#!/bin/bash
# 消息系统合规性检查
COMPLIANCE_LOG="/var/log/mesg_compliance.log"
check_compliance() {
local score=0
local total=6
echo "=== 消息系统合规性检查 ==="
echo "检查时间: $(date)"
echo ""
# 检查1: root用户是否禁用消息
echo "检查1: root用户消息状态"
if sudo -u root mesg 2>/dev/null | grep -q "is n"; then
echo "✓ root用户消息已禁用"
((score++))
else
echo "✗ root用户消息未禁用(安全风险)"
fi
# 检查2: 系统账户是否禁用消息
echo -e "\n检查2: 系统账户消息状态"
local system_users=$(getent passwd | grep -E ":/bin/false$|:/usr/sbin/nologin$" | cut -d: -f1)
local all_ok=true
for user in $system_users; do
if sudo -u "$user" mesg 2>/dev/null | grep -q "is y"; then
echo "警告: 系统账户 $user 启用了消息"
all_ok=false
fi
done
if $all_ok; then
echo "✓ 所有系统账户消息已禁用"
((score++))
else
echo "✗ 有系统账户启用了消息"
fi
# 检查3: 是否有全局策略
echo -e "\n检查3: 系统范围消息策略"
if grep -r "mesg" /etc/profile /etc/bash.bashrc 2>/dev/null | grep -q "mesg n"; then
echo "✓ 存在禁用消息的全局策略"
((score++))
else
echo "✗ 无全局消息策略"
fi
# 检查4: 审计日志配置
echo -e "\n检查4: 消息审计日志"
if [ -f "/var/log/mesg_audit.log" ] || [ -f "/var/log/user_messages" ]; then
echo "✓ 存在消息审计日志"
((score++))
else
echo "✗ 无消息审计日志"
fi
# 检查5: write命令权限
echo -e "\n检查5: write命令权限"
write_path=$(which write 2>/dev/null)
if [ -n "$write_path" ]; then
perms=$(stat -c "%a" "$write_path")
if [ "$perms" = "4755" ] || [ "$perms" = "4750" ]; then
echo "✓ write命令权限正确"
((score++))
else
echo "✗ write命令权限可能存在问题: $perms"
fi
fi
# 检查6: talk服务状态
echo -e "\n检查6: talk服务状态"
if systemctl is-active talk.socket 2>/dev/null | grep -q "active"; then
echo "警告: talk服务正在运行(安全考虑)"
else
echo "✓ talk服务未运行"
((score++))
fi
# 计算结果
echo -e "\n=== 检查结果 ==="
echo "得分: $score/$total"
percentage=$((score * 100 / total))
echo "合规率: $percentage%"
if [ $percentage -ge 80 ]; then
echo "状态: ✓ 合规"
elif [ $percentage -ge 60 ]; then
echo "状态: ⚠ 部分合规"
else
echo "状态: ✗ 不合规"
fi
}
# 运行检查
check_compliance | tee -a "$COMPLIANCE_LOG"
EOF
chmod +x /tmp/mesg_compliance_check.sh
echo "合规性检查脚本已创建: /tmp/mesg_compliance_check.sh"
}
# 5. 备份和恢复配置
backup_restore_config() {
echo "备份和恢复消息配置..."
# 备份函数
backup_mesg_config() {
local backup_dir="/backup/mesg_config_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
echo "备份消息配置到: $backup_dir"
# 备份系统配置文件
cp /etc/profile "$backup_dir/"
cp /etc/bash.bashrc "$backup_dir/" 2>/dev/null
cp /etc/bashrc "$backup_dir/" 2>/dev/null
# 备份用户配置
for user in $(getent passwd | cut -d: -f1); do
user_home=$(getent passwd "$user" | cut -d: -f6)
if [ -f "$user_home/.bashrc" ]; then
user_backup_dir="$backup_dir/users/$user"
mkdir -p "$user_backup_dir"
cp "$user_home/.bashrc" "$user_backup_dir/"
cp "$user_home/.profile" "$user_backup_dir/" 2>/dev/null
fi
done
# 创建恢复脚本
cat > "$backup_dir/restore.sh" << 'EOF'
#!/bin/bash
# 消息配置恢复脚本
BACKUP_DIR=$(dirname "$0")
echo "恢复消息配置..."
echo "备份目录: $BACKUP_DIR"
# 恢复系统配置
if [ -f "$BACKUP_DIR/profile" ]; then
echo "恢复/etc/profile..."
sudo cp "$BACKUP_DIR/profile" /etc/profile
fi
if [ -f "$BACKUP_DIR/bash.bashrc" ]; then
echo "恢复/etc/bash.bashrc..."
sudo cp "$BACKUP_DIR/bash.bashrc" /etc/bash.bashrc
fi
if [ -f "$BACKUP_DIR/bashrc" ]; then
echo "恢复/etc/bashrc..."
sudo cp "$BACKUP_DIR/bashrc" /etc/bashrc
fi
# 恢复用户配置
if [ -d "$BACKUP_DIR/users" ]; then
for user_dir in "$BACKUP_DIR/users"/*; do
if [ -d "$user_dir" ]; then
user=$(basename "$user_dir")
user_home=$(getent passwd "$user" | cut -d: -f6 2>/dev/null)
if [ -n "$user_home" ] && [ -d "$user_home" ]; then
echo "恢复用户 $user 配置..."
if [ -f "$user_dir/.bashrc" ]; then
cp "$user_dir/.bashrc" "$user_home/"
fi
if [ -f "$user_dir/.profile" ]; then
cp "$user_dir/.profile" "$user_home/" 2>/dev/null
fi
fi
fi
done
fi
echo "恢复完成"
EOF
chmod +x "$backup_dir/restore.sh"
# 创建压缩包
tar -czf "$backup_dir.tar.gz" -C "$backup_dir" .
echo "备份压缩包: $backup_dir.tar.gz"
}
# 恢复函数
restore_mesg_config() {
local backup_file=$1
if [ ! -f "$backup_file" ]; then
echo "错误: 备份文件不存在: $backup_file"
return 1
fi
echo "从 $backup_file 恢复配置..."
# 解压备份
temp_dir=$(mktemp -d)
tar -xzf "$backup_file" -C "$temp_dir"
# 运行恢复脚本
if [ -f "$temp_dir/restore.sh" ]; then
bash "$temp_dir/restore.sh"
else
echo "错误: 恢复脚本不存在"
fi
# 清理临时目录
rm -rf "$temp_dir"
}
echo "备份和恢复功能已定义"
echo "使用: backup_mesg_config 进行备份"
echo "使用: restore_mesg_config <备份文件> 进行恢复"
}
# 6. 监控和报警
monitoring_alerting() {
echo "配置监控和报警..."
cat > /usr/local/bin/mesg_monitor.sh << 'EOF'
#!/bin/bash
# 消息系统监控脚本
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/mesg_monitor.log"
ALERT_THRESHOLD=10 # 每分钟消息阈值
# 监控消息活动
monitor_messages() {
local last_count=0
while true; do
# 获取当前消息计数
current_count=$(find /dev/pts/ -type c -name "[0-9]*" 2>/dev/null | wc -l)
active_messages=$((current_count - last_count))
# 记录日志
echo "$(date) - 活动消息: $active_messages" >> "$LOG_FILE"
# 检查阈值
if [ $active_messages -gt $ALERT_THRESHOLD ]; then
send_alert "高消息活动" "检测到高消息活动: $active_messages 条/分钟"
fi
# 检查异常用户
check_abnormal_users
last_count=$current_count
sleep 60
done
}
# 检查异常用户
check_abnormal_users() {
# 获取消息状态变化的用户
who | while read user tty rest; do
status=$(sudo -u "$user" mesg 2>/dev/null)
# 检查状态是否频繁变化
if grep -q "用户 $user 状态变化" "$LOG_FILE" | tail -5; then
send_alert "状态频繁变化" "用户 $user 消息状态频繁变化"
fi
done
}
# 发送报警
send_alert() {
local subject=$1
local message=$2
echo "ALERT: $subject - $message" >> "$LOG_FILE"
# 发送邮件
echo "$message" | mail -s "消息系统报警: $subject" "$ALERT_EMAIL"
# 发送系统日志
logger -p user.alert "mesg监控: $subject - $message"
}
# 启动监控
monitor_messages
EOF
chmod +x /usr/local/bin/mesg_monitor.sh
echo "监控脚本已创建: /usr/local/bin/mesg_monitor.sh"
# 创建systemd服务
cat > /etc/systemd/system/mesg-monitor.service << EOF
[Unit]
Description=Message System Monitor
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mesg_monitor.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
echo "Systemd服务已创建: /etc/systemd/system/mesg-monitor.service"
}
# 7. 主菜单
main_menu() {
while true; do
clear
echo "=== 消息系统管理和安全配置 ==="
echo ""
echo "1. 系统范围策略配置"
echo "2. 安全审计配置"
echo "3. 入侵检测配置"
echo "4. 合规性检查"
echo "5. 备份和恢复配置"
echo "6. 监控和报警配置"
echo "7. 运行所有配置"
echo "0. 退出"
echo ""
read -p "选择: " choice
case $choice in
1) system_wide_policy ;;
2) security_audit_config ;;
3) intrusion_detection ;;
4) compliance_check ;;
5) backup_restore_config ;;
6) monitoring_alerting ;;
7)
echo "运行所有配置..."
system_wide_policy
security_audit_config
intrusion_detection
compliance_check
backup_restore_config
monitoring_alerting
echo "所有配置完成"
;;
0)
echo "退出"
exit 0
;;
*)
echo "无效选择"
;;
esac
echo ""
read -p "按回车键继续..."
done
}
# 运行主菜单
main_menu
故障排查:
which mesg
# 应该输出: /usr/bin/mesg
# 如果没有,安装coreutils
sudo apt-get install coreutils
# mesg需要修改tty设备权限
ls -la $(tty)
# 输出示例: crw--w---- 1 user tty
# 如果用户不在tty组,可能无法修改
# 检查用户组
groups $USER
# 确保用户在tty组中
# 如果没有,添加用户到tty组
sudo usermod -a -G tty $USER
# 重新登录使更改生效
# 某些shell配置可能覆盖mesg设置
# 检查~/.bashrc, ~/.profile, ~/.bash_profile
grep -n "mesg" ~/.bashrc ~/.profile ~/.bash_profile 2>/dev/null
# 如果有冲突的行,注释掉或修改
# 例如: mesg n || true
# 系统可能强制设置了策略
grep -r "mesg" /etc/profile /etc/bash.bashrc 2>/dev/null
# 如果是只读文件系统或受限环境
# 检查是否是容器或chroot环境
ls -la / | head -5
# 手动修改tty权限测试
TTY=$(tty)
echo "当前TTY: $TTY"
# 尝试启用消息
chmod g+w $TTY
ls -la $TTY
# 应该显示: crw--w----
# 尝试禁用消息
chmod g-w $TTY
ls -la $TTY
# 应该显示: crw-------
# 使用strace查看命令执行
strace mesg y 2>&1 | tail -20
# 查看系统调用,检查错误
自动配置方法:
# 添加到 ~/.bashrc
# 登录时自动设置
if [ -t 0 ]; then
mesg n 2>/dev/null || true
fi
# 或根据条件设置
if [ -t 0 ]; then
# 工作时间启用,非工作时间禁用
hour=$(date +%H)
if [ $hour -ge 9 ] && [ $hour -lt 18 ]; then
mesg y
else
mesg n
fi
fi
# 在 /etc/profile 中为所有用户设置
# 添加在文件末尾
if [ -t 0 ]; then
# 生产服务器:默认禁用
mesg n 2>/dev/null || true
# 或根据用户组设置
if groups $USER | grep -q "developers"; then
mesg y
else
mesg n
fi
fi
# 创建PAM模块配置文件
sudo nano /etc/pam.d/mesg
# 内容:
# session optional pam_exec.so /usr/local/bin/set_mesg.sh
# 创建设置脚本
cat > /usr/local/bin/set_mesg.sh << 'EOF'
#!/bin/bash
# PAM登录时设置mesg
if [ "$PAM_TYPE" = "open_session" ]; then
sudo -u "$PAM_USER" mesg n
fi
EOF
chmod +x /usr/local/bin/set_mesg.sh
# 创建systemd用户服务
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/mesg.service << 'EOF'
[Unit]
Description=Set mesg on login
After=default.target
[Service]
Type=oneshot
ExecStart=/usr/bin/mesg n
RemainAfterExit=yes
[Install]
WantedBy=default.target
EOF
# 启用服务
systemctl --user enable mesg.service
systemctl --user start mesg.service
# 添加cron任务
crontab -e
# 添加以下行:
# 每天9点启用消息
0 9 * * * mesg y
# 每天18点禁用消息
0 18 * * * mesg n
# 每分钟检查并设置
* * * * * /usr/local/bin/check_and_set_mesg.sh
# 在 /etc/bash.bashrc 或 /etc/profile 中添加
# SSH登录时特殊处理
if [ -n "$SSH_CONNECTION" ]; then
mesg n
fi
# 根据终端类型设置
case $(tty) in
/dev/tty[0-9]*)
mesg y # 控制台终端启用
;;
/dev/pts/[0-9]*)
mesg n # 伪终端禁用
;;
esac
mesg在现代系统中的角色:
# 在生产服务器上禁用消息,防止干扰
# 添加到安全加固脚本
echo "禁用终端消息..." >> /var/log/hardening.log
mesg n
# 检查安全合规
if mesg | grep -q "is y"; then
echo "警告: 消息接收已启用" >> /var/log/security.log
fi
# 在Docker容器中通常不需要消息
# Dockerfile中禁用
RUN echo "mesg n" >> /etc/profile
# 在Kubernetes中
# Pod securityContext中可能需要处理
securityContext:
capabilities:
drop: ["SYS_TTY_CONFIG"]
# 在自动化任务中防止消息干扰
setup_automation() {
# 保存当前状态
MESG_STATE=$(mesg | awk '{print $2}')
# 禁用消息
mesg n
# 运行自动化任务
./automated_task.sh
# 恢复原状态
mesg $MESG_STATE
}
# 在Jenkins/GitLab CI中
pipeline {
agent any
stages {
stage('Setup') {
steps {
sh '''
# 禁用消息防止干扰
mesg n || true
echo "消息接收已禁用"
'''
}
}
}
}
# 在现代桌面环境中,mesg可能被其他机制替代
# 但仍在某些场景有用
# GNOME终端可能忽略mesg设置
# 检查桌面环境
echo $XDG_CURRENT_DESKTOP
# 使用dbus或其他机制替代
dbus-send --session --type=method_call \
--dest=org.gnome.Terminal \
/org/gnome/Terminal \
org.gnome.Terminal.SetProperty \
string:'allow-remote' boolean:false
# 保持与旧脚本的兼容性
# 许多旧脚本可能依赖mesg
# 包装函数保持兼容
legacy_mesg() {
if [ "$1" = "y" ]; then
# 现代替代方案
systemctl --user import-environment DISPLAY
elif [ "$1" = "n" ]; then
# 现代禁用方案
systemctl --user unset-environment DISPLAY
else
# 默认行为
command mesg "$@"
fi
}