ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu开启root远程SSH登录:配置与安全加固实战

Ubuntu开启root远程SSH登录:配置与安全加固实战 1. 为什么要碰root远程登录这个“禁区”先说结论Ubuntu默认不允许root用户通过SSH远程登录这事在Linux运维圈里几乎是人尽皆知的“出厂设置”。但你如果真去过生产环境或自己折腾过服务器大概率会遇到某些场景——比如自动化脚本需要以root身份执行、某些老旧软件安装时必须root登录、或者你管理的是一台没有控制台只有网络出口的云主机——这时候“默认不允许”就变成了一个必须解决的拦路虎。我当年第一次折腾这个是在一台临时测试服务器上。那时候不懂为什么要禁用root登录只觉得“我自己的机器root密码都设好了凭什么不让我登”于是翻遍了大大小小的博客踩了一堆坑最后才搞清楚这背后的安全逻辑和正确的开启姿势。如果你也在被同样的问题卡住这篇就把整个思路、配置、排查一次讲透。适合谁看三类人一是刚接触Linux服务器、连root和sudo都还没分清楚的新手二是正在给云服务器或虚拟机重装系统后、需要恢复root远程管理能力的人三是在写自动化部署脚本时需要对多台Ubuntu做统一root配置的运维/开发。不管你是哪一类按下面的步骤走基本不会翻车。1.1 CentOS能登、Ubuntu不能登差的不是一个配置项用惯了CentOS的人转过来用Ubuntu通常会很不适应CentOS默认装了openssh-server之后只要给root设了密码直接就能用root去SSH登录可Ubuntu这边明明密码没错、服务也开着、端口也通就是反复提示Permission denied。问题出在哪里关键在于两个发行版对sshd_config的默认策略不同。Ubuntu从很早的版本开始就在/etc/ssh/sshd_config里把PermitRootLogin的默认值设成了prohibit-password也就是“禁止用密码登录root”但允许密钥登录有些发行版甚至直接是no。再加上Ubuntu安装时根本就没让你设置过root密码你用的那个用户是sudo组里的普通用户双重的“障碍”叠加在一起表现就是远程死活连不上。从安全角度讲这个设计是合理的。root是系统的最高权限账户如果允许密码远程登录攻击者就有机会对root密码做暴力破解一旦中招服务器就等于拱手让人了。而Ubuntu主推的方式是普通用户通过SSH登录之后再sudo -i或sudo su -提权到root这样攻击者无法直接对root发起认证尝试安全面就小很多。1.2 你确定真的需要root远程登录吗在动手之前我建议你先冷静三分钟问自己一个问题开root远程登录到底是想解决什么需求我见过不少用户开root远程登录理由五花八门某些国产软件、闭源程序的安装脚本写死了“必须root用户执行”写自动化脚本时不想每次sudo输密码图省事管理的服务器太多不想挨个配sudo用户甚至有人只是觉得“root登录显得很专业”。如果你的需求属于前两类可以继续往下看如果是最后一种我更建议你改用sudo方案。因为即使是原意开root登录的运维老手通常也会在开完之后马上把密码登录关掉仅保留密钥登录或者直接配置prohibit-password模式也就是“允许root用密钥登录、但禁止密码登录”两头兼顾。这是一个很重要的思路我们最终的目标不是让root远程登录变得方便而是让root远程登录变得既可用、又不那么容易被攻破。1.3 方案选型改配置、加密钥、还是跳板机开启root远程登录的路径不止一条我个人把常见方案归成三类按推荐程度排序方案操作复杂度安全性适用场景方案A修改sshd_config并重启sshd低中取决于认证方式临时调试、内网环境、明确知道风险时方案B仅允许root密钥登录prohibit-password低高生产环境、长期管理方案C通过跳板机/堡垒机登录后跳转高很高企业级、多服务器管理本文的核心操作是方案A但会反复强调如何收敛到方案B的安全水平。为什么要先讲“改配置”而不是直接上密钥因为很多场景下你手头只有密码还没生成过密钥对先把密码登录跑通再回头做密钥加固是大多数人实际会走的路径。完全不让密码登录、一上来就是密钥那种做法对新手来说反而容易卡在半路。2. 动手前的环境检查别等失败了才后悔人不能打无准备的仗改服务器配置也一样。我见过太多人兴冲冲改完sshd_config、重启服务之后发现自己被锁在门外——因为改错参数、或者防火墙没放行、又或者sshd直接起不来了。所以这一节的内容一定要在动任何配置之前做。2.1 版本和网络基础检查先确认几件最基本的事情# 查看系统版本 lsb_release -a # 查看sshd是否已安装 dpkg -l | grep openssh-server # 查看sshd服务状态 systemctl status ssh执行下来无非三种情况没装openssh-server那就先sudo apt update sudo apt install openssh-server -y装上装完再继续。已装但没启动sudo systemctl start ssh sudo systemctl enable ssh顺手设成开机自启。已装且正常运行直接往下走。同时确认一下IP和端口。ip addr看当前IP地址ss -tlnp | grep 22确认22端口在监听。如果你的服务器是云主机后面还要去云厂商控制台查安全组规则这一步最容易忽略。我自己就曾在一个云服务商的环境里本地改了半天的SSH配置最后发现是安全组压根没放行22端口白折腾一下午。2.2 先备份sshd_config这是保命动作这个习惯我强烈建议你直接刻进肌肉记忆改任何系统配置文件之前先备份。sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %F)这行命令会在/etc/ssh/下生成一个带日期的备份文件比如sshd_config.bak.2025-01-15。万一改坏了想还原直接sudo cp回去就行。而且备份还有个额外好处你以后翻看旧文件能对比出自己到底改了哪些参数排查问题时非常有价值。有一次我就是靠对比备份文件发现另一台服务器当时加了一行AllowUsers白名单结果新用户怎么都登不上排查半天才找到原因。2.3 了解当前sshd的有效配置这里有个很实用的技巧直接查看sshd当前生效的配置而不用去翻那一大堆注释掉的默认值。sudo sshd -T | grep -i permitrootloginsshd -T会输出sshd实际使用的有效配置不是配置文件原文而是解析后的结果。这一步能让你在修改之前先清楚当前PermitRootLogin到底是什么状态。多数情况下你会看到permitrootlogin prohibit-password这行输出清楚地告诉我们Ubuntu默认允许root登录但只允许公钥认证不允许密码认证。这也是整篇文章要解决的真正“症结”。注意sshd -T只能由root或sudo用户执行普通用户执行会提示权限不足。3. 核心步骤实操一步步开启root密码远程登录环境检查完了下面进入最核心的实操环节。我会把每一步的命令、参数含义、可能遇到的报错都写清楚你照着执行即可。3.1 给root设置一个合格的密码Ubuntu默认的root账户是没有密码的也就是说哪怕你切换到root系统显示的也是类似rootubuntu:~#但实际并没有可用的密码。这就导致即便你改了sshd_configroot也没有密码可供登录。所以第一步是给root设置密码。sudo passwd root执行后会让你先输入当前用户的sudo密码如果有提示然后两次输入新的root密码。这里有个容易踩的坑输入密码时终端不会显示任何字符连星号都不会有这是正常现象别以为键盘坏了。我第一次给root设密码时还以为自己没输进去按了好几次回车后来才知道Linux终端设计如此。密码设置建议长度至少12位以上混合大小写字母、数字、特殊字符不要用生日、电话、简单的连续键盘序列如123456、qwerty如果是测试环境可以适当降低标准但生产环境必须严格。设置完成后可以先在本地测试一下su -切换到root是否成功确认密码没问题再继续改SSH配置。这一步能帮你把“密码题”和“SSH配置题”分开排查避免出了问题后不知道是密码不对还是配置不对。3.2 修改sshd_config关键是PermitRootLogin这一行接下来就是核心环节了。用你熟悉的编辑器打开配置文件我用的是vim也可以用nano看个人喜好sudo vim /etc/ssh/sshd_config找到这一行#PermitRootLogin prohibit-password注意前面有个#说明这是注释状态。Ubuntu的默认配置文件通常是把实际生效的默认值以注释形式展示真正生效的值是sshd程序的编译默认值。所以你要做的不是简单把这行取消注释而是要改成自己想要的值。如果你只是想临时开启密码登录root把这一行改成PermitRootLogin yes如果你希望保留一定安全性、只允许root用密钥登录改成PermitRootLogin prohibit-password两个值的选择逻辑我在前面说过这里再强调一次yes是“完全放行”prohibit-password是“禁止密码认证、但允许密钥认证”。从安全角度我个人的建议是仅在调试阶段用yes调试完之后改回prohibit-password或直接关掉root登录。这里还有一个容易忽略的细节配置文件里可能存在多处PermitRootLoginSSH读取时以第一个出现的有效值为准。所以改之前最好先用grep -n PermitRootLogin /etc/ssh/sshd_config查一下有哪些行避免改了一处、另一处还在“捣乱”。3.3 确认没有其他参数挡住root登录光改PermitRootLogin还不够有时候你还会被其他参数拦住。常见的几个“拦路虎”PermitEmptyPasswords如果这个值是yesSSH会拒绝任何空密码账户登录。root有密码的话不受影响但如果你的root密码没设成功这里就会拦你。PasswordAuthentication这是另一个关键开关。如果它是no那么即使PermitRootLogin yesroot依然无法用密码登录因为整个密码认证都被关了。Ubuntu默认这个值是yes但如果之前有人改过就得注意。AllowUsers/DenyUsers这两个是用户级白名单/黑名单。如果AllowUsers里没写root或者DenyUsers里写了root那root一样登不进来跟PermitRootLogin没有关系。排查完这些之后保存退出。修改前多看一眼这几项能省下后面一大半的排查时间。3.4 重启sshd服务让配置生效配置文件改完了接下来要重启SSH服务。这一步的操作细节很重要因为重启SSH服务不会断开现有连接但如果你配置写错了新连接会全部失败。这里有一个特别实用的“防锁死”技巧先开一个额外的终端窗口保持SSH连接不断开再执行重启命令。这样即使配置写错你还能通过已有连接把配置改回来。重启服务的方式有两种效果基本等价sudo systemctl restart ssh # 或 sudo systemctl restart sshdUbuntu上使用ssh这个unit名称更标准因为它对应openssh-server这个包但很多人在CentOS上习惯了sshd在Ubuntu上直接敲sshd也常常能用因为系统会做兼容映射。如果你用的是旧版写法比如service ssh restart也能达到同样效果。重启之前建议先做一次配置语法检查sudo sshd -t如果输出没有任何提示说明语法没问题如果提示Missing privilege separation directory之类那可能是目录权限问题需要先处理。sshd -t这个检查步骤非常有用因为它不会影响正在运行的sshd进程只做配置解析和校验。养成“改配置前先-t检查”的习惯能避免90%的人为配置错误。接着查看服务状态sudo systemctl status ssh看到active (running)就说明服务正常。如果你心态够稳也可以做个更深入的验证ss -tlnp | grep :22这个命令确认22端口仍在监听。3.5 从客户端验证root登录是否成功服务端配置完了接下来就是验证。我建议分别测试两种方式从本机回环地址登录测试ssh root127.0.0.1这一步能排除网络因素专门验证SSH认证链路是否通畅。如果本机能登进去说明服务端配置没问题如果本机都不行那问题肯定出在SSH配置上。从远程机器登录测试# 在Windows的PowerShell、macOS/Linux的终端里执行 ssh root你的服务器IP首次连接会出现The authenticity of host ...的提示问你是否确认连接输入yes回车。这个是正常的因为客户端还没保存过该服务器的指纹信息。之后会让你输入root密码输入正确就能进入root的shell环境了。到这里root远程密码登录就已经成功开启了。注意如果你是通过云平台创建的Ubuntu服务器在验证SSH连接之前先去云控制台的安全组确认22端口已对来源IP放行。安全组没放行的话客户端会一直卡在连接超时而你服务端怎么检查都是正常的很容易让人误判。3.6 让root登录更安全的三个追加步骤辛苦开完了root登录千万不要就这样丢在那边用。我强烈建议你再花几分钟做这三件事把安全级别拉回来第一步关闭密码登录只保留密钥登录。把sshd_config里的PermitRootLogin改成prohibit-password再添加你本机的公钥到服务器的/root/.ssh/authorized_keys文件里重启sshd。以后登录靠密钥密码认证直接禁掉暴力破解基本归零。生成密钥对的操作在客户端执行ssh-keygen -t ed25519 -C 你的备注信息然后把公钥复制到服务器ssh-copy-id root你的服务器IP这个工具会自动把公钥追加到服务器的authorized_keys中方便得很。如果没有ssh-copy-id命令也可以手动复制公钥内容追加。第二步开启fail2ban主动防御。sudo apt install fail2ban -y sudo systemctl enable --now fail2banfail2ban会监控SSH登录日志在短时间内多次认证失败的IP会被自动封禁一段时间。我见过一个真实案例一台开了root密码登录的VPS公网IP裸露在外没用fail2ban的当天就被扫了上千次SSH登录尝试配置好fail2ban之后暴力扫描的请求基本被挡在门外日志瞬间安静了。第三步把SSH端口从22改成不常见的端口。编辑/etc/ssh/sshd_config找到#Port 22去掉注释并改成如Port 22345这样的高位端口然后重启sshd。这算一种“通过隐藏来降低暴露面”的思路。它不能防住有目的的定向攻击但能挡住绝大多数的自动化扫描。改端口后客户端连接命令要相应加上-p 22345参数或者修改客户端的~/.ssh/config。这三步做完你的root远程登录才算是真正能“见光”的配置而不是一个随时可能被攻破的口子。4. 常见问题与排查技巧实录这部分我会把实操中最常遇到报错和排查方法整理出来。这些错误我基本都踩过每一项都是真实的“血泪经验”。4.1 Permission denied (publickey,password)怎么办这是开启root登录过程中最常见的报错没有之一。看到这个错误先别慌按顺序排查第一步确认PermitRootLogin真的改对了。很多人改了配置文件但忘了重启sshd导致配置根本没生效。执行sudo sshd -T | grep permitrootlogin看当前有效值如果还是prohibit-password说明没生效。第二步确认PasswordAuthentication没有把密码认证关掉。用sudo sshd -T | grep passwordauthentication查看如果结果是no把配置改成yes再重启。第三步确认root密码真的设置成功了。在服务器本地su -切一下root如果提示密码错误说明之前passwd root没有成功重新设置。第四步如果以上都没问题试试把客户端主机的旧known_hosts缓存清掉。有些情况下你服务器的SSH host key变了比如重装系统客户端会因为指纹不匹配而拒绝连接表现类似Permission denied。执行ssh-keygen -R 你的服务器IP之后重新连接重新接受新的host key即可。4.2 连接超时Connection timed out怎么排查如果客户端卡在Connection timed out那问题基本不在SSH认证上而是网络链路不通。几个检查点服务器是否在运行、sshd是否监听在服务器本地执行systemctl status ssh和ss -tlnp | grep 22。防火墙是否放行22端口Ubuntu默认带ufw执行sudo ufw status查看状态。如果是active需要sudo ufw allow 22/tcp。云安全组是否放行登录云控制台检查安全组入方向规则确保22端口对你的来源IP开放。服务器IP是否正确如果服务器有多个网卡、或者绑定了弹性IP确认你连的是对的那个IP。我遇到一个特别典型的案例服务器有两个网卡一个内网IP、一个公网IP结果公网IP那块的防火墙规则没有放行22端口而内网可以连导致我误判了很久最后用tcpdump抓包才发现问题。4.3 重启sshd后新连接进不来但旧连接还活着这是一种“半死不活”的状态你开着的一个SSH窗口还正常但新开一个窗口怎么也连不上。这种情况十有八九是配置写错了但因为旧连接还在systemd不会强制断开它。处理方法很简单利用旧连接执行sudo sshd -t定位配置错误然后修好再sudo systemctl restart ssh。永远不要在没有“保底连接”的情况下重启SSH服务这句话我写过很多遍每次都是血泪换来的。另外有个细节Ubuntu的systemctl restart ssh失败的时候不一定代表服务起不来了有时是因为配置里出现了无法解析的参数。先sshd -t它会直接告诉你哪一行有语法错误效率最高。4.4 问题排查速查表现象可能原因快速诊断命令解决方向Permission denied (publickey,password)配置未生效/password认证被禁sudo sshd -T | grep -E permitrootlogin|passwordauthentication修正配置并重启ssh确认root密码Connection timed out防火墙/安全组/网络不通sudo ufw status、控制台安全组放行22端口确认IPConnection refusedsshd未启动或端口不对systemctl status ssh、ss -tlnp | grep ssh启动sshd核对端口Host key verification failed服务器指纹变化ssh-keygen -R IP删除老指纹后重连密码输对了仍被拒绝AllowUsers/DenyUsers限制sudo sshd -T | grep -i allowusers将root加入白名单或移除黑名单还有一个容易被忽略的坑修改了sshd_config之后一定确保文件没有权限问题。如果sshd_config的权限是0666或所有者错误sshd可能直接拒绝读取或启动失败。正确的权限是644所有者root。4.5 再提一句别忘了PAM配置的影响某些Ubuntu版本在/etc/ssh/sshd_config里会有一行UsePAM yes默认开启。PAM可插拔认证模块会在SSH之外额外做一层认证校验尤其是它关联到/etc/security/access.conf或pam_access.so模块的时候即使你的PermitRootLogin yes配置没错PAM层也能把root登录给挡住。如果你改了sshd_config还是被拒绝检查一下/etc/pam.d/sshd文件看看有没有类似account required pam_access.so的行。有的话再检查/etc/security/access.conf是否限制了root。这种“配置看起来都对、但就是登不上”的场景多半就是PAM在背后捣鬼。我在一次帮朋友排查时遇到过所有常规检查都通过最后发现是access.conf里有一行- : root : ALL把root全给禁了。删掉那行之后问题瞬间解决。最后的个人体会与建议先把话说在前头root远程登录不是不能用但要用得明白、用得克制。我个人在实际操作中的体会是很多服务器被入侵并不是因为开了root登录本身而是因为开完之后忘了做安全收敛——密码设得弱、22端口裸奔、没有fail2ban、没有密钥认证。如果你只是图一时方便就把PermitRootLogin yes一改丢在那里那跟把家门钥匙放在门口的脚垫底下没什么区别。我自己的做法是这样开发测试环境可以开root密码登录但密码一定是随机强密码记录在密码管理器里生产环境则严格使用prohibit-password加密钥登录22端口改成高位端口配合fail2ban和云安全组白名单。坦白讲这套组合算不上“极客级安全”但应对绝大多数网络扫描和自动化攻击已经绰绰有余。最后再分享一个实用小技巧改完配置后不要急着把所有旧连接都关掉。先在同一个SSH会话里把sshd -T的结果确认一遍再用新窗口做一次完整登录测试确认一切正常后再退出旧窗口。这多花的几十秒能让你避免“改完配置进不去、旧连接又全断了”的至暗时刻。如果这篇帮到了你希望你能记住的不是某条命令而是那个最核心的观念root权限是一把锋利的刀远程登录是一种暴露的姿态两者叠加在一起就必须有额外的安全措施来兜底。至于具体怎么配照着上面的步骤走基本不会出错。
返回列表