☰
Kali Linux SSH服务与防火墙配置实战:从安装到持久化
2026/10/18 19:21:22 网站建设 项目流程

1. 为什么在Kali里折腾SSH和防火墙值得单独写一篇

很多人第一次在Kali上开SSH,都是被逼的。要么是虚拟机里敲命令太憋屈,想用宿主机终端连进去;要么是手头只有一台笔记本,想把Kali当远程跳板机跑扫描任务;要么是实验室里几台机器要互传文件,懒得插U盘。结果一上手就发现,Kali的SSH默认状态跟Ubuntu、CentOS完全不是一回事——服务没起、端口没开、防火墙规则还跟你想的不一样。我见过太多人卡在“Connection refused”或者“Permission denied”上,折腾一晚上最后放弃,继续在虚拟机窗口里一个字一个字地敲。

这篇东西就是把我自己反复踩过的坑、验证过的配置流程,以及那些文档里不会写的细节,一次性讲清楚。核心就三件事:怎么把SSH服务跑起来、怎么让防火墙放行、怎么让配置在重启后依然生效。听起来简单,但每一步都有坑。比如Kali Rolling版本默认不带SSH服务端,你得先装;比如UFW和iptables在Kali里的默认策略跟Debian系其他发行版有微妙差异;再比如你改了sshd_config之后忘了检查语法,服务直接起不来,连报错都看不懂。

适合谁看?如果你是刚接触Kali的新手,照着做能少走两小时弯路;如果你已经用过SSH但总在防火墙这关卡住,这里有针对Kali的排查链路;如果你是要在实验环境里批量配置多台Kali,后面也有可复用的配置模板和批量操作思路。我不讲那些“SSH是加密远程登录协议”的教科书定义,直接上操作、上原理、上我踩过的坑。

2. Kali里SSH服务的安装与首次启动

2.1 先确认你的Kali到底有没有SSH服务端

很多人上来就systemctl start ssh,然后报错“Unit ssh.service not found”。这不是命令错了,是Kali默认根本没装SSH服务端。Kali的定位是渗透测试发行版,默认只装了SSH客户端(让你去连别人),服务端(让别人连你)需要手动安装。这个设计逻辑跟Ubuntu Server完全相反,所以习惯Ubuntu的人第一次用Kali会懵。

确认方法很简单,两条命令:

# 查看ssh服务端是否安装 dpkg -l | grep openssh-server # 查看ssh客户端是否安装(这个默认一定有) dpkg -l | grep openssh-client

如果第一条命令没有任何输出,说明服务端没装。第二条命令应该能看到openssh-client的包信息。这里有个细节:Kali Rolling版本在2020年之后的镜像里,连客户端都可能精简掉,但大多数场景下客户端是保留的,因为渗透测试经常要SSH连靶机。

注意:不要用apt install ssh这个命令。ssh是一个元包,在不同发行版里指向不同东西。在Kali里直接装openssh-server最稳妥,避免装错包。

2.2 安装openssh-server的正确姿势

安装本身不复杂,但有几个前置动作容易被忽略。首先更新源,Kali的源如果没配好,安装会失败或者装到旧版本:

sudo apt update sudo apt install openssh-server -y

装完之后,系统会自动生成主机密钥(host keys),这些密钥在/etc/ssh/目录下,文件名类似ssh_host_rsa_key、ssh_host_ecdsa_key。如果你之前手动删过这些文件,或者从别的机器克隆了Kali镜像,密钥可能冲突,导致客户端连接时报“Host key verification failed”。解决办法是删掉/etc/ssh/ssh_host_*然后重新生成:

sudo rm /etc/ssh/ssh_host_* sudo dpkg-reconfigure openssh-server

这个dpkg-reconfigure命令会重新跑一遍配置脚本,自动生成新的主机密钥。我试过在克隆的虚拟机里直接启动SSH,客户端连上去报密钥不匹配,排查了半天才发现是克隆导致密钥重复。这个坑在批量部署Kali虚拟机的时候特别常见。

2.3 启动服务并设置开机自启

装完之后,SSH服务默认可能是disabled状态。Kali用的是systemd,所以操作很标准:

# 启动服务 sudo systemctl start ssh # 设置开机自启 sudo systemctl enable ssh # 查看状态 sudo systemctl status ssh

状态输出里看到active (running)就说明服务跑起来了。但这里有个隐藏问题:Kali在某些版本里,ssh.service和ssh.socket是两套机制。如果你用systemctl status ssh看到的是socket激活模式,那服务可能不是常驻的,而是按需启动。对于实验环境,我建议统一用ssh.service,避免socket模式带来的端口监听延迟。

检查方法:

sudo systemctl is-enabled ssh sudo systemctl is-active ssh

两个命令分别返回enabled和active才算配置到位。如果is-enabled返回disabled,即使当前跑着,重启后也会失效。

2.4 验证SSH是否真的在监听

服务状态显示running,不代表端口一定在监听。可能配置文件有语法错误,服务启动了但没绑定端口。用这条命令确认:

ss -tlnp | grep :22

或者老一点的系统用netstat -tlnp | grep :22。输出里应该看到LISTEN状态和对应的进程名sshd。如果什么都没看到,说明服务虽然显示running,但实际没监听端口,这时候要去查/var/log/auth.log或者journalctl -u ssh看具体报错。

我遇到过一种情况:sshd_config里写了Port 2222,但防火墙只开了22,结果本地ss能看到2222在监听,但远程连不上。所以端口监听和防火墙放行是两件事,必须分开验证。

3. sshd_config里那些真正影响连接的参数

3.1 默认配置里哪些参数必须改

Kali的/etc/ssh/sshd_config默认配置其实挺保守的,但有几个参数在实际使用中会带来麻烦。我按重要性排个序:

参数默认值建议值原因
PermitRootLoginprohibit-passwordno禁止root直接登录,用普通用户+sudo
PasswordAuthenticationyes按需实验环境可保留yes,生产环境建议no
PubkeyAuthenticationyesyes密钥登录更安全,保留
Port22按需改非标准端口可减少扫描噪音
ListenAddress0.0.0.0按需多网卡时指定监听地址

PermitRootLogin这个参数特别值得说。Kali默认是prohibit-password,意思是root不能用密码登录,但可以用密钥。很多人改成yes图方便,结果实验环境被扫到就麻烦。我的建议是保持no,用普通用户登录后再sudo -i切root,多一步但安全很多。

3.2 改完配置必须做的语法检查

这是我最想强调的一点:改完sshd_config千万不要直接restart。先跑语法检查:

sudo sshd -t

如果配置有问题,这条命令会直接告诉你哪一行错了。没有输出就说明语法OK。我见过太多人改完配置直接systemctl restart ssh,结果服务起不来,SSH断了,只能去虚拟机控制台救火。先检查再重启,这个习惯能省你很多时间。

检查通过后再重启:

sudo systemctl restart ssh

重启后再次用ss -tlnp确认端口监听正常,然后用另一台机器或另一个终端尝试连接。不要关掉当前SSH会话再重连,万一新配置有问题,你至少还有一个活着的会话可以回滚。

3.3 密钥登录的配置细节

密码登录虽然方便,但在实验环境里经常被扫描器爆破。配密钥登录其实不复杂,但有几个细节容易漏。

生成密钥对(在客户端机器上操作):

ssh-keygen -t ed25519 -C "kali-lab"

ed25519比RSA更短更快,现代系统都支持。生成后把公钥传到Kali上:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@kali-ip

如果ssh-copy-id不可用,手动追加也行:

cat ~/.ssh/id_ed25519.pub | ssh user@kali-ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

这里权限很关键。~/.ssh必须是700,authorized_keys必须是600。权限不对的话,SSH会静默忽略密钥,只让你输密码,而且不报错。我排查过好几次“密钥明明传了但还是要密码”的问题,最后都是权限不对。

服务端这边,确认sshd_config里:

PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys

改完记得sshd -t检查再重启。

3.4 监听端口和地址的取舍

默认监听0.0.0.0:22,意思是所有网卡的所有IP的22端口都接受连接。在实验环境里,如果你的Kali有多张网卡(比如NAT一张、Host-Only一张),可能只想让Host-Only那张接受SSH。这时候改ListenAddress:

ListenAddress 192.168.56.10 Port 22

这样只有指定IP的22端口监听,NAT网卡那边就连不上了。这个配置在隔离实验环境里很有用,避免暴露到不该暴露的网络。

改端口的话,注意SELinux(Kali默认没开)和防火墙都要同步改。我一般不建议改端口,因为Kali的实验环境通常在内网,改端口带来的安全收益有限,反而增加配置复杂度。如果确实要改,记得sshd -t检查,防火墙规则同步更新。

4. Kali防火墙的默认状态与放行策略

4.1 Kali默认防火墙到底开没开

这是最容易让人困惑的地方。Kali默认没有启用任何防火墙。ufw status会显示inactive,iptables -L会显示空规则链。也就是说,刚装好的Kali,所有端口都是开放的,SSH只要服务跑起来就能连。

但问题在于,很多人从别的教程里抄了ufw enable,结果把自己关在外面。因为UFW默认策略是deny incoming,你一启用,所有入站连接全断,包括你正在用的SSH。如果你是在远程连Kali,启用UFW的瞬间你就掉线了。

所以第一步永远是:先确认防火墙状态,再决定要不要动它。

sudo ufw status verbose sudo iptables -L -n

如果ufw是inactive,iptables是空规则,那SSH连不上就不是防火墙的问题,去查服务监听和网络连通性。

4.2 UFW的规则配置与SSH放行顺序

如果你确实需要启用防火墙(比如Kali放在公网可访问的环境),那顺序必须是:先放行SSH,再启用UFW。

# 先放行SSH端口 sudo ufw allow 22/tcp # 再启用 sudo ufw enable

如果SSH改过端口,比如2222:

sudo ufw allow 2222/tcp sudo ufw enable

启用后检查规则:

sudo ufw status numbered

输出里应该看到22/tcp ALLOW IN Anywhere。如果没看到,说明规则没生效,检查是不是先enable后allow了。

注意:如果你已经启用了UFW并且SSH断了,别慌。去虚拟机控制台(VMware/VirtualBox的窗口)登录,然后sudo ufw allow 22/tcp,再sudo ufw reload。如果控制台也进不去,重启进恢复模式,ufw disable。

4.3 iptables直接操作的场景

有些实验环境要求用iptables而不是UFW,比如你要模拟特定网络策略。iptables的规则是即时生效的,但默认重启后丢失。要持久化得用iptables-persistent:

sudo apt install iptables-persistent -y

放行SSH的规则:

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

第二条规则很重要,它允许已建立的连接继续通信。没有这条,你SSH连上去之后,回包可能被拦,表现为能连上但卡死。

保存规则:

sudo netfilter-persistent save

这个命令会把当前iptables规则写到/etc/iptables/rules.v4,重启后自动加载。

4.4 UFW和iptables的优先级关系

这里有个容易搞混的点:UFW底层就是iptables的前端。你ufw allow之后,实际是在iptables里插了规则。如果你同时手动改iptables,可能跟UFW的规则冲突。我的建议是二选一,要么全用UFW,要么全用iptables,不要混着来。

如果非要混用,记住UFW的规则链在iptables里是ufw-user-input,你手动加的规则如果在INPUT链里排在UFW之前,可能覆盖UFW的策略。排查的时候用iptables -L -n --line-numbers看规则顺序,顺序错了就全乱。

5. 从连接失败到连通的完整排查链路

5.1 第一层:网络通不通

SSH连不上,先别急着查SSH配置。第一步永远是确认网络层通不通:

ping kali-ip

如果ping不通,后面都不用查了。检查Kali的IP、网卡模式(NAT/桥接/Host-Only)、宿主机防火墙。虚拟机环境里最常见的是网卡模式选错,比如Kali是NAT模式,但你从宿主机用Host-Only的网段去连,肯定不通。

ping通了但SSH连不上,继续下一步。

5.2 第二层:端口开没开

在Kali本机确认端口监听:

ss -tlnp | grep :22

有输出说明服务在监听。没输出说明SSH服务没跑起来,回去查systemctl status ssh和journalctl -u ssh。

本机确认监听正常后,从客户端测端口连通性:

nc -zv kali-ip 22

或者用telnet kali-ip 22。如果显示Connection refused,说明端口没监听或者防火墙REJECT。如果显示Connection timed out,说明防火墙DROP或者网络中间有设备拦截。

5.3 第三层:防火墙规则有没有拦

在Kali上查防火墙:

sudo ufw status verbose sudo iptables -L -n -v

重点看INPUT链的默认策略和规则。如果默认策略是DROP且没有放行22的规则,那就是防火墙拦了。加规则:

sudo ufw allow 22/tcp

或者iptables:

sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT

注意-I是插入到链首,-A是追加到链尾。如果前面有DROP规则,-A加的规则永远匹配不到,必须用-I。

5.4 第四层:SSH服务本身的认证问题

端口通了,但连接时报Permission denied或者Authentication failed,那就是认证层的问题。常见原因:

  • 密码错了(大小写、键盘布局)
  • 用户不存在或被锁定
  • sshd_config里AllowUsers或DenyUsers限制了
  • 密钥权限不对
  • PAM模块拦截

排查方法:在Kali上看/var/log/auth.log,里面会记录每次登录尝试的详细原因。比如Failed password for invalid user说明用户名错了,Authentication refused: bad ownership or modes说明密钥文件权限不对。

5.5 第五层:那些诡异的“能连上但卡住”

有一种情况最折磨人:SSH能连上,输入密码后卡住,或者连上后命令执行很慢。这通常是DNS反向解析导致的。sshd_config里有个UseDNS参数,默认可能是yes,服务端会尝试反向解析客户端IP,如果DNS不可用,就会卡几十秒。

解决办法:

UseDNS no GSSAPIAuthentication no

改完sshd -t检查再重启。这两个参数在实验环境里建议都关掉,能显著提升连接速度。

6. 让配置在重启后依然生效的持久化方案

6.1 SSH服务自启的确认

systemctl enable ssh只是设置了开机自启,但如果你用的是ssh.socket模式,可能行为不一样。确认方法:

systemctl list-unit-files | grep ssh

输出里ssh.service应该是enabled。如果是disabled,重新enable。另外检查有没有ssh.socket被enable了,如果两个都enable,可能冲突。建议只保留ssh.service:

sudo systemctl disable ssh.socket sudo systemctl enable ssh.service

6.2 防火墙规则的持久化

UFW的规则默认就是持久的,ufw enable之后规则会写到/etc/ufw/下的配置文件,重启自动加载。但有个例外:如果你手动改了/etc/ufw/user.rules但没ufw reload,重启后可能不生效。保险做法是每次改完规则跑一次:

sudo ufw reload

iptables的话,前面说了用netfilter-persistent save。但注意,如果你同时装了UFW和iptables-persistent,重启时可能互相覆盖。建议只用一个。

6.3 配置文件备份与版本管理

sshd_config改多了容易乱,建议改之前备份:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

如果实验环境有多台Kali,可以把调好的配置存到版本控制里,批量分发。我自己的做法是维护一个sshd_config模板,新机器装好SSH后直接覆盖,然后sshd -t检查,重启服务。这样能保证所有机器的配置一致,排查问题的时候少一个变量。

6.4 重启后的验证清单

每次重启Kali后,按这个清单过一遍:

  1. systemctl status ssh— 服务是否running
  2. ss -tlnp | grep :22— 端口是否监听
  3. sudo ufw status— 防火墙规则是否加载
  4. 从客户端nc -zv kali-ip 22— 端口是否可达
  5. 实际SSH登录一次 — 认证是否正常

这五步走完,基本能覆盖99%的“重启后连不上”问题。我见过太多人重启后直接连,连不上就慌,其实按清单一步步查,问题很快定位。

7. 多场景下的配置取舍与经验心得

7.1 虚拟机NAT模式下的SSH配置

NAT模式下,Kali的IP是VMware/VirtualBox分配的,宿主机不能直接访问,需要配端口转发。以VirtualBox为例,在虚拟机设置里加一条NAT端口转发规则:宿主端口2222,虚拟机端口22。然后从宿主机ssh -p 2222 user@127.0.0.1就能连上。

这种场景下,Kali内部的防火墙通常不用动,因为NAT转发是在虚拟化层做的,流量到了Kali内部已经是本地连接。但如果你在Kali里启用了UFW且没放行22,照样连不上。所以NAT模式下,SSH服务跑起来+UFW放行22,两个条件缺一不可。

7.2 桥接模式下的局域网访问

桥接模式下,Kali跟宿主机在同一局域网,IP是路由器分配的。这种场景最方便,同网段任何机器都能SSH连。但要注意:

  • 如果局域网有DHCP,Kali的IP可能变,建议配静态IP或者在路由器上绑MAC
  • 防火墙必须放行22,因为流量是从外部进来的
  • 如果局域网有安全策略,可能拦截22端口,换个端口试试

桥接模式下我一般会改SSH端口到非标准值,减少被扫描的概率。虽然实验环境通常安全,但养成习惯没坏处。

7.3 多台Kali批量配置的思路

如果你要配多台Kali(比如实验集群),一台台手动改太慢。我的做法是写个简单的shell脚本,把sshd_config模板、防火墙规则、密钥分发都自动化。核心步骤:

  1. 用sshpass或预置密钥做初始认证
  2. 分发sshd_config模板
  3. 跑sshd -t检查
  4. 重启服务
  5. 配置UFW规则
  6. 验证端口监听

这个脚本不需要多复杂,几十行就能搞定。关键是每步都要有错误检查,比如sshd -t失败就中止,不要盲目重启。

7.4 那些文档里不会写的细节

最后分享几个我踩过的坑:

坑一:sshd_config里的注释符号。#开头的行是注释,但有些参数默认值就是注释掉的。你改的时候如果直接在注释行后面加内容,比如#Port 22改成#Port 22然后另起一行写Port 2222,没问题。但如果你把#去掉改成Port 22,又没改端口号,那就跟默认一样。改配置的时候看清楚是注释还是生效行。

坑二:UFW的allow和limit。ufw allow 22是允许所有连接,ufw limit 22是限制连接频率(防爆破)。实验环境用allow就行,limit在某些扫描场景下会误拦。

坑三:SSH连接慢但能连上。除了UseDNS,还可能是GSSAPIAuthentication导致的。两个都关掉,连接速度立竿见影。

坑四:改了端口后ss -tlnp看不到。检查sshd_config里是不是有多个Port行,或者ListenAddress限制了。sshd -t能查出语法问题,但逻辑问题得自己看。

坑五:密钥登录突然失效。检查~/.ssh和authorized_keys权限,检查sshd_config里PubkeyAuthentication是不是被注释了,检查AuthorizedKeysFile路径对不对。这三个查完基本能解决。

这些细节在官方文档里要么一笔带过,要么分散在不同章节,实际用的时候得自己串起来。我写这篇就是想把这条链路一次性打通,让你在Kali上开SSH、配防火墙这件事上,不再卡壳。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询