基于TCP_Wrappers与iptables构建轻量级堡垒机实战指南

📅 2026/7/1 22:26:41
基于TCP_Wrappers与iptables构建轻量级堡垒机实战指南
1. 项目概述从零构建一个轻量级堡垒机在运维工作中我们常常面临一个经典难题如何安全、可控地管理成百上千台服务器直接开放SSH端口给所有运维人员无异于将钥匙挂在门上。商业堡垒机动辄数十万对于中小团队来说成本高昂。今天我们就来聊聊如何利用Linux系统自带的“老伙计”——TCP_Wrappers和iptables亲手搭建一个具备核心管控能力的轻量级堡垒机。这不仅仅是两个命令的堆砌而是一套完整的安全访问控制思想的落地实践。这个方案的核心价值在于“透明”和“灵活”。它不像JumpServer或齐治堡垒机那样提供完整的Web操作界面和会话审计而是通过在网络层和访问控制层嵌入规则实现访问源限制、命令黑白名单、实时拦截三大核心功能。想象一下你只需要在一台作为“跳板”的服务器上配置好规则所有试图通过它访问后端业务服务器的流量都会先经过这套规则的严格审查。无论是防止误操作、限制特定IP访问还是实时封禁可疑行为都能轻松实现。特别适合那些预算有限但又对基础安全有刚性需求的团队或者作为已有安全体系的一个有力补充。2. 核心组件深度解析TCP_Wrappers与iptables的角色在开始动手之前我们必须吃透这两个工具的工作原理。它们并非简单的“防火墙”而是工作在OSI模型不同层级的访问控制大师。2.1 TCP_Wrappers应用层的守门人TCP_Wrappers常被称作“TCP包装器”它是一个工作在应用层的访问控制工具。它的工作模式非常巧妙它并不替代像sshd或vsftpd这样的服务进程而是作为这些服务与网络之间的一个“中间人”或“代理”。工作原理当一个客户端比如你的SSH客户端尝试连接服务器时连接请求首先会被系统的inetd或xinetd超级守护进程对于现代系统很多服务通过systemd的socket激活或直接监听但TCP_Wrappers库依然会被调用接收。在服务进程如/usr/sbin/sshd真正处理这个连接之前TCP_Wrappers的库函数libwrap会被调用。这个库函数会去检查两个核心配置文件/etc/hosts.allow 允许访问的规则列表。/etc/hosts.deny 拒绝访问的规则列表。检查顺序是“allow - deny - 默认允许”。也就是说系统会先看hosts.allow如果匹配则允许如果不匹配再看hosts.deny如果匹配则拒绝如果两个文件都不匹配则默认允许连接。它的核心能力在于基于主机名/IP/网络的访问控制 你可以精确到某个IP或一个CIDR网段。简单的命令执行 在规则匹配时可以触发外部命令这是实现我们堡垒机“联动封禁”功能的关键。轻量级 配置简单无需重启服务修改即时生效对于已建立连接无效对新连接有效。注意 并非所有服务都支持TCP_Wrappers。一个服务是否支持取决于它是否在编译时链接了libwrap库。你可以使用ldd /usr/sbin/sshd | grep libwrap命令来检查sshd是否支持。绝大多数主流发行版预装的OpenSSH都支持。2.2 iptables网络层的交通警察如果说TCP_Wrappers是检查每个想要进入大楼访客的邀请函那么iptables就是控制整条街道车流方向的交警和路障系统。它工作在网络层和传输层是Linux内核Netfilter框架的用户态管理工具。工作原理iptables通过定义一系列的规则Rules并将其组织成链Chains中。数据包进入网络协议栈后会依次经过这些预定义的链链中的每条规则都会检查数据包的特征如源/目标IP、端口、协议、连接状态等。如果数据包匹配某条规则则执行该规则对应的动作Target如ACCEPT接受、DROP丢弃、REJECT拒绝并回复、LOG记录日志等。我们主要利用它的几个核心链INPUT链 处理发往本机的数据包。我们可以用它来保护堡垒机自身。FORWARD链 处理经过本机转发的数据包。这是实现堡垒机跳转功能的关键当堡垒机作为跳板数据包不是终止于它而是由它转发给后端服务器时数据包会经过FORWARD链。OUTPUT链 处理从本机发出的数据包。它的核心能力在于基于网络五元组源IP、源端口、目标IP、目标端口、协议的精确过滤。网络地址转换NAT 这是实现端口转发、让堡垒机成为透明代理的核心。PREROUTING链和POSTROUTING链专门用于此。连接状态跟踪state模块 能识别NEW新连接、ESTABLISHED已建立连接、RELATED相关连接如FTP的数据连接等状态让规则设置更智能、更安全。强大的扩展匹配 可以匹配MAC地址、数据包速率、字符串内容等。二者协同工作模式在我们的堡垒机方案中TCP_Wrappers和iptables是纵深防御的两道关卡。通常我们可以让TCP_Wrappers作为第一道精细化的应用层过滤比如基于用户名或客户端的简单判断并在其hosts.deny中配置规则在拒绝访问的同时触发脚本调用iptables将违规IP在网络层彻底封禁。这样就实现了从“拒绝本次服务”到“拒绝所有网络访问”的升级管控。3. 堡垒机方案设计与实施路径理解了工具我们来规划整个堡垒机的架构。我们的目标是搭建一台堡垒主机Bastion Host所有运维人员必须先登录这台主机然后通过它跳转到内网的其他业务服务器。同时在这台堡垒主机上实施严格的访问控制。3.1 整体架构与数据流假设我们有以下环境运维人员电脑 IP为10.0.0.100堡垒机 IP为192.168.1.10 系统为 CentOS 7/8 或 Rocky Linux 8。后端业务服务器 IP为192.168.1.100 仅允许来自堡垒机192.168.1.10的SSH访问。理想的数据流运维人员从10.0.0.100SSH连接到堡垒机192.168.1.10:22。连接请求首先经过堡垒机的iptablesINPUT链目标IP是堡垒机自身。通过后由TCP_Wrappers对sshd服务进行审查。审查通过用户成功登录堡垒机。用户在堡垒机上执行ssh user192.168.1.100连接后端服务器。此时从堡垒机192.168.1.10到192.168.1.100的流量会经过堡垒机的iptablesOUTPUT链源IP是堡垒机和FORWARD链如果涉及路由转发。更重要的是后端服务器192.168.1.100的iptables INPUT链应该只允许源IP为192.168.1.10的SSH连接。这是安全的关键一环。我们的配置将主要集中在堡垒机上实现对其自身SSH服务的访问控制并为其配置转发能力。后端服务器的防火墙配置是另一个独立但至关重要的部分。3.2 分步配置实操3.2.1 堡垒机基础环境与iptables配置首先确保堡垒机的IP转发功能已开启这是它能作为跳板的基础。# 临时开启IP转发 sysctl -w net.ipv4.ip_forward1 # 永久生效编辑 /etc/sysctl.conf echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p接下来配置iptables规则。我们的策略是默认拒绝显式允许。先清空现有规则设置默认策略。# 停止并禁用firewalld如果使用CentOS/RHEL 7 systemctl stop firewalld systemctl disable firewalld # 安装iptables-services如果未安装 yum install -y iptables-services # 保存并清空现有iptables规则谨慎操作最好在本地终端操作避免把自己关在外面 iptables -F iptables -X iptables -Z iptables -t nat -F # 设置默认策略INPUT和FORWARD链默认拒绝OUTPUT默认允许 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 允许本地回环接口流量这是系统内部通信必需的 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # 允许已建立的连接和相关的连接通过这是保证已有连接不中断的关键 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT现在开始添加我们需要的规则1. 允许特定IP段如10.0.0.0/24访问堡垒机的SSH端口22iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT-s 10.0.0.0/24 源IP地址范围。-p tcp --dport 22 协议为TCP目标端口为22。-m state --state NEW 匹配新的连接请求。-j ACCEPT 执行接受动作。2. 允许堡垒机转发来自可信源10.0.0.0/24去往后端服务器192.168.1.0/24的流量iptables -A FORWARD -s 10.0.0.0/24 -d 192.168.1.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT这条规则允许运维人员通过堡垒机新建连接到后端服务器的SSH。3. 可选但推荐配置SNAT使后端服务器看到的流量源IP是堡垒机简化后端服务器的防火墙规则iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -d 192.168.1.0/24 -j MASQUERADE-t nat 操作NAT表。-A POSTROUTING 在路由决策之后、数据包发出之前修改数据包。-j MASQUERADE 自动使用发出数据包的网络接口的IP做源地址转换。这对于堡垒机使用动态IP如拨号的情况特别有用。如果堡垒机是固定IP也可以使用-j SNAT --to-source 192.168.1.10。4. 保存iptables规则并设置开机自启# 对于CentOS 7 service iptables save # 规则会保存到 /etc/sysconfig/iptables systemctl enable iptables systemctl start iptables # 检查规则 iptables -L -n -v iptables -t nat -L -n -v3.2.2 TCP_Wrappers精细化管理现在配置TCP_Wrappers实现更灵活的控制。例如我们允许整个10.0.0.0/24网段访问但单独拒绝其中的10.0.0.200这个IP。编辑/etc/hosts.allowsshd: 10.0.0.0/255.255.255.0这表示允许10.0.0.0/24网段访问sshd服务。编辑/etc/hosts.denysshd: 10.0.0.200 sshd: ALL: spawn (/usr/local/bin/ban_ip.sh %a) deny第一行明确拒绝10.0.0.200。第二行这是一个关键配置。它表示默认拒绝所有其他主机访问sshd服务。并且在拒绝的同时会触发一个动作spawn执行一个脚本/usr/local/bin/ban_ip.sh并将客户端的IP地址%a作为参数传递给这个脚本。表示后台执行。这个ban_ip.sh脚本就是实现与iptables联动的核心。它的内容如下#!/bin/bash # /usr/local/bin/ban_ip.sh ATTACKER_IP$1 # 记录日志 echo $(date %Y-%m-%d %H:%M:%S) - TCP_Wrappers denied and banned IP: $ATTACKER_IP /var/log/tcpwrap-ban.log # 使用iptables封禁该IP的所有访问不仅仅是22端口 /sbin/iptables -I INPUT -s $ATTACKER_IP -j DROP # 同样封禁其转发流量 /sbin/iptables -I FORWARD -s $ATTACKER_IP -j DROP创建脚本并赋予执行权限chmod x /usr/local/bin/ban_ip.sh实操心得hosts.deny中的ALL: deny规则一定要放在最后并且配合spawn动作。这样任何未被hosts.allow明确允许的连接尝试都会被拒绝并立即触发iptables封禁。这是一种从“应用层拒绝”升级到“网络层封禁”的主动防御策略可以有效应对端口扫描和暴力破解。3.2.3 后端服务器加固堡垒机建好了后端服务器的门也要关好。在后端服务器192.168.1.100上配置iptables只接受来自堡垒机的SSH连接。# 后端服务器上操作 iptables -P INPUT DROP iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 关键规则只允许堡垒机IP访问22端口 iptables -A INPUT -s 192.168.1.10 -p tcp --dport 22 -m state --state NEW -j ACCEPT # 保存并启用规则根据系统操作4. 高级功能扩展与优化配置基础堡垒功能实现后我们可以进一步强化它使其更智能、更易管理。4.1 利用iptables限制连接速率与防御暴力破解单纯的允许/拒绝规则还不够。我们可以用iptables的limit或recent模块来防御SSH暴力破解。使用recent模块动态封禁# 1. 创建一个自定义链管理SSH iptables -N SSH_PROTECT iptables -A INPUT -p tcp --dport 22 -j SSH_PROTECT # 2. 在自定义链中设置规则 # 规则解释检查IP是否已在“黑名单”SSH_BLACKLIST中如果在则丢弃。 iptables -A SSH_PROTECT -m recent --name SSH_BLACKLIST --rcheck --seconds 3600 -j DROP # 规则解释将新的SSH连接请求记录到“SSH_TRY”列表。 iptables -A SSH_PROTECT -m recent --name SSH_TRY --set # 规则解释在60秒内如果来自同一IP的连接尝试超过3次第4次开始则将其加入“SSH_BLACKLIST”黑名单并丢弃本次连接同时记录日志。 iptables -A SSH_PROTECT -m recent --name SSH_TRY --rcheck --seconds 60 --hitcount 4 -j LOG --log-prefix SSH Brute Force: --log-level warn iptables -A SSH_PROTECT -m recent --name SSH_TRY --rcheck --seconds 60 --hitcount 4 -m recent --name SSH_BLACKLIST --set -j DROP # 规则解释如果连接尝试在合理范围内则移除本次记录并跳回INPUT链继续处理最终会被前面的ACCEPT规则接受。 iptables -A SSH_PROTECT -m recent --name SSH_TRY --remove -j RETURN这个配置实现了一分钟内同一IP尝试SSH连接超过3次则自动封禁该IP一小时。这能极大缓解暴力破解攻击。4.2 实现运维用户与命令审计轻量级堡垒机缺乏完整的会话录像功能但我们可以通过简单的改造实现基础审计。方法一修改用户Shell环境为所有通过堡垒机登录的运维用户设置一个特殊的shell或登录脚本。在/etc/passwd中将用户的shell从/bin/bash改为一个自定义的包装脚本例如/usr/local/bin/audit_shell.sh。/usr/local/bin/audit_shell.sh脚本内容#!/bin/bash LOG_FILE/var/log/ssh_audit/$(date %Y%m%d)_$(whoami).log { echo Session started $(date) echo User: $(whoami) echo From: $SSH_CLIENT echo Command history: # 启动一个带审计的bash export HISTFILE$LOG_FILE.hist export HISTTIMEFORMAT%F %T bash echo Session ended $(date) } | tee -a $LOG_FILE然后在/etc/passwd中修改相应用户行operator:x:1001:1001::/home/operator:/usr/local/bin/audit_shell.sh这样该用户的所有登录会话和执行的命令都会被记录到/var/log/ssh_audit/目录下的日志文件中。注意事项这种方法有局限性用户可以通过启动其他shell如/bin/sh或重定向绕过。它更适用于信任度较高的环境或作为补充手段。方法二使用Snoopy或类似库进行系统级审计安装像snoopy这样的系统调用跟踪器它可以记录所有通过execve()系统调用执行的命令无论用户如何启动。配置后所有命令及其参数都会被记录到syslog中再由rsyslog转发到中央日志服务器。这是更全面、更难绕过的方法。4.3 配置集中式日志收集安全设备的日志分散在各处是无效的。我们需要将堡垒机和关键服务器的日志集中起来分析。在堡垒机上配置rsyslog转发编辑/etc/rsyslog.conf取消注释或添加以下行将日志发送到中央日志服务器假设IP为192.168.1.200。*.* 192.168.1.200:514重启rsyslog服务systemctl restart rsyslog。在中央日志服务器上配置接收同样编辑/etc/rsyslog.conf启用UDP/TCP日志接收模块并定义存储路径。module(loadimudp) input(typeimudp port514) module(loadimtcp) input(typeimtcp port514)然后可以配置模板将不同主机、不同设施的日志分门别类存储。使用Logstash Elasticsearch Kibana (ELK) 或 Graylog对于更强大的日志管理和分析可以部署专业的日志栈。Logstash负责收集和解析来自rsyslog的日志Elasticsearch负责存储和索引Kibana提供可视化界面让你可以轻松地搜索“哪些IP在暴力破解SSH”、“某个用户执行了哪些高危命令”等。5. 常见问题排查与运维技巧在实际部署和运维中你肯定会遇到各种问题。这里记录一些典型场景和排查思路。5.1 连接失败问题排查流程图当运维人员报告“无法通过堡垒机连接后端服务器”时可以按照以下路径排查1. 检查本地到堡垒机的连通性 └─ 失败检查本地网络、堡垒机IP、防火墙云服务器安全组 └─ 成功进入下一步 2. 检查能否登录堡垒机 └─ 失败检查堡垒机sshd服务状态、端口监听、iptables INPUT规则、TCP_Wrappers配置、/var/log/secure日志。 └─ 成功登录后进入下一步 3. 在堡垒机上检查到后端服务器的连通性 └─ 失败检查后端服务器IP、网络路由、后端服务器防火墙。 └─ 成功进入下一步 4. 在堡垒机上尝试SSH连接后端服务器 └─ 失败检查后端服务器sshd服务、后端服务器iptables规则是否只允许堡垒机IP、密钥认证或密码是否正确。 └─ 成功问题可能出在用户环境或审计脚本上。5.2 典型问题与解决方案速查表问题现象可能原因排查命令与解决方案SSH连接堡垒机超时1. 堡垒机防火墙iptablesDROP了连接。2. 云平台安全组未放行22端口。3. 网络路由不通。1.iptables -L -n -v查看INPUT链计数。2. 检查云控制台安全组规则。3.traceroute 堡垒机IP。连接堡垒机被拒绝 (Connection refused)1. sshd服务未运行。2. sshd监听端口不是22或被修改。1.systemctl status sshd。2.netstat -tlnp | grep :22检查/etc/ssh/sshd_config中的Port。登录堡垒机时提示“Connection closed by foreign host”1. TCP_Wrappers拒绝hosts.deny。2. PAM认证模块失败。3. 用户shell配置错误如审计脚本语法错误。1. 查看/var/log/secure寻找refused connect from字样。2. 查看/var/log/secure中PAM错误信息。3. 检查/etc/passwd中用户shell指向的脚本是否存在、是否有执行权限、语法是否正确。能从堡垒机ping通后端但ssh连接失败1. 后端服务器防火墙拒绝。2. 后端服务器sshd服务问题。3. 堡垒机FORWARD链或NAT规则未正确配置。1. 在后端服务器执行iptables -L -n -v。2. 检查后端服务器sshd服务与日志。3. 在堡垒机用tcpdump -i any port 22 and host 后端服务器IP抓包看请求是否发出、是否被NAT。iptables规则重启后丢失规则未保存。使用service iptables saveCentOS 6/7或iptables-save /etc/iptables/rules.v4Debian/Ubuntu保存。确保iptables服务开机自启。TCP_Wrappers规则似乎不生效1. 服务不支持libwrap。2. 规则语法错误如多余空格。3. 规则顺序问题allow优先。1.ldd $(which sshd) | grep libwrap。2. 检查hosts.allow和hosts.deny文件格式。3. 记住检查顺序allow - deny - 默认允许。5.3 日常运维与监控技巧定期审查封禁日志每天检查/var/log/tcpwrap-ban.log和iptables日志如果开启了LOG规则分析被封禁的IP判断是误封还是攻击。备份防火墙规则每次对iptables进行重大修改前先备份现有规则iptables-save /etc/iptables/backup_$(date %Y%m%d).rules。出问题时可以快速恢复iptables-restore /备份文件。使用脚本动态管理信任IP如果运维人员IP经常变动可以写一个脚本通过读取某个受控的URL或文件自动更新iptables和hosts.allow中的IP列表。结合CI/CD可以实现运维人员入职/离职自动开通/关闭权限。监控连接数使用netstat -an \| grep :22 \| grep ESTABLISHED \| wc -l监控当前SSH连接数。如果异常增高可能是被入侵或出现了异常连接。堡垒机本身的安全加固禁用密码登录强制使用密钥对认证。修改/etc/ssh/sshd_configPasswordAuthentication no。更改SSH端口为非标准端口如2222并在iptables中相应修改。限制堡垒机上的用户权限只给必要的sudo权限。定期更新系统和软件包。这套基于TCP_Wrappers和iptables的堡垒机方案虽然不如商业产品功能花哨但它足够轻量、透明、且完全受控。通过深入理解其原理并灵活组合你可以构建出贴合自身业务需求的、坚固的初级安全防线。在运维成本和安全需求之间它无疑是一个极佳的平衡点。