SELinux (Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。NSA是在Linux社区的帮助下开发了一种访问控制体系,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。
简单来说, SELinux 会限制程序的访问权限、监控端口。在Centos 7上,开启 SELinux ,服务修改端口可能会出现启动失败的情况
以下为开启 SELinux 后 SSH 修改端口后启动异常的现象及解决方案:
问题现象:
修改 SSH 默认监听端口 22 为 13579,重启服务,发现启动失败了,通过 journalctl 命令查看串口日志,其中一行错误比较重要,提示权限错误
error: Bind to port 13579 on 0.0.0.0 failed: Permission denied
root@BJ-CentOS7 ~ # grep Port /etc/ssh/sshd_config
Port 13579
root@BJ-CentOS7 ~ # systemctl restart sshd.service
Job for sshd.service failed because the control process exited with error code. See "systemctl status sshd.service" and "journalctl -xe" for details.
root@BJ-CentOS7 ~ # journalctl -xn 10
-- Logs begin at Mon 2018-04-30 13:25:08 CST, end at Mon 2018-05-14 16:16:35 CST. --
May 14 16:15:53 test systemd[1]: Unit sshd.service entered failed state.
May 14 16:15:53 test systemd[1]: sshd.service failed.
May 14 16:16:35 test systemd[1]: sshd.service holdoff time over, scheduling restart.
May 14 16:16:35 test sshd[10403]: error: Bind to port 13579 on 0.0.0.0 failed: Permission denied.
May 14 16:16:35 test systemd[1]: Starting OpenSSH server daemon...
-- Subject: Unit sshd.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit sshd.service has begun starting up.
May 14 16:16:35 test sshd[10403]: fatal: Cannot bind any address.
May 14 16:16:35 test systemd[1]: sshd.service: main process exited, code=exited, status=255/n/a
May 14 16:16:35 test systemd[1]: Failed to start OpenSSH server daemon.
-- Subject: Unit sshd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit sshd.service has failed.
--
-- The result is failed.
May 14 16:16:35 test systemd[1]: Unit sshd.service entered failed state.
May 14 16:16:35 test systemd[1]: sshd.service failed.
问题分析:
看到权限错误,首先想到的是好像这里 SELinux 开启的情况下,允许服务使用的端口会受限,验证确实是 SELinux 在搞鬼:
SELinux 状态为 Enforcing(强制模式),SSH允许监听端口为 22
root@BJ-CentOS7 ~ # getenforce
Enforcing
root@BJ-CentOS7 ~ # semanage port -l | grep ssh
ssh_port_t tcp 22
解决方案:
1. 简单粗暴,关闭 SELinux :
1.1 临时关闭,可以正确监听 SSH 服务在自定义端口,但是重启服务器会失效
[root@test ~]# setenforce 0
[root@test ~]# getenforce
Permissive
[root@test ~]# systemctl restart sshd.service
[root@test ~]# netstat -anpt | grep ssh
tcp 0 0 0.0.0.0:13579 0.0.0.0:* LISTEN 10589/sshd
1.2 永久关闭:
修改 /etc/selinux/config 文件中配置 SELINUX=disabled,重启服务器使其生效
root@BJ-CentOS7 ~ # sed -i '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config
2. 给 SSH 服务添加允许使用的端口,再次重启服务,成功监听 SSH 服务在自定义端口
root@BJ-CentOS7 ~ # semanage port -d -t ssh_port_t -p tcp 13579
root@BJ-CentOS7 ~ # semanage port -l | grep ssh
ssh_port_t tcp 13579, 22
root@BJ-CentOS7 ~ # systemctl restart sshd.service
root@BJ-CentOS7 ~ # getenforce; netstat -anpt | grep ssh
Enforcing
tcp 0 0 0.0.0.0:13579 0.0.0.0:* LISTEN 10558/sshd