本来想想ssh连接linux没有很复杂,但是多次扮演“技术支持”的角色之后发现原来里面还是有不少坑的。这篇文章目的是希望能把这件简单的事情所涉及的步骤整理并知识结构体系化。因为以下命令都需要进入到linux服务器环境中执行,所以主要用于解决火眼仿真linux后无法使用网探连接的问题。
1. 基础知识:linux服务器的主要2大派系
看到这个标题希望各种用Arch的大神不要拍死我。事实上linux发行版众多,派系而言远远不止2个。但是本文主要针对于debian和redhat两大派系讲的。因为在生产服务器市场很难找到以opensuse或者Arch之类的。
debian系最主要的特征是apt和dpkg两个命令。apt全称为Advanced Package Tool
,用于软件的安装与卸载,最常用的命令就是apt-get install 包名
。dpkg全称为Debian Package
,dpkg是一个比apt更为底层的包管理工具,我最经常用的比如dpkg -l
列出所有已安装的包或者是dpkg -i 本地deb包路径
安装本地包。根据distrowatch显示,目前已知基于debian并且存活的linux发行版大概有137个,比较出名的有:ubuntu,Mint,kali,deepin,deft linux.
对应于debian系的apt和dpkg命令,redhat系发行版有yum和rpm命令。其功能和命令行参数几近类似。yum全称为 Yellowdog Updater, Modified
。但是值得一提的是,yum基于python的一个扩展库,这就导致一个很明显的问题是系统自带yum依赖的那个python版本不能动,不能升级也不能降级,否则很容易导致yum不能正常工作。其解决方案是用dnf代替yum.yum和rpm常用功能很简单,不会时直接百度就好了。与redhat一家的还有:centos和fedora.具体三者区别参考于:https://linux-audit.com/difference-between-centos-fedora-rhel
2. 基础知识:了解服务器基本信息
我为什么要花这么长时间去讲linux的两大派系呢?当遇到我们尝试ssh连接目标服务器时,首先需要知道目标是属于哪个发行版以及包管理方法。这对无论是遇到问题寻求解决方案还是后续执行命令都是有帮助的。一般情况下我们可以寻求于 /etc/os-release
和uname
命令。可以看到详细的发行版名称,版本号,linux内核版本号。这样当后续遇到任何问题无论是网上搜索还是寻求别人帮助都会方便很多。
下图是Ubuntu的执行结果:
spring@Ubuntu:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
spring@Ubuntu:~$ uname -m # x86_64代表64位系统
x86_64
spring@Ubuntu:~$ uname -r # linux内核版本号
4.15.0-33-generic
下图是CentOS的执行结果:
[spring@localhost ~]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
[spring@localhost ~]$ uname -m # x86_64代表64位系统
x86_64
[spring@localhost ~]$ uname -r # linux内核版本号
3.10.0-862.el7.x86_64
3.检查ssh服务是否安装
当我们意识到通过常规ssh命令无法正常连接服务器时,首先考虑的第一个问题是服务器是否安装了ssh服务。其包名都为 openssh-server
。
debian系检查ssh服务是否安装如下图:
spring@Ubuntu:~$ dpkg -l | grep "openssh-server"
ii openssh-server 1:7.6p1-4 amd64 secure shell (SSH) server, for secure access from remote machines
redhat系检查ssh服务是否安装如下图:
[spring@localhost ~]$ rpm -qa | grep "openssh-server"
openssh-server-7.4p1-16.el7.x86_64
如果如上图显示,说明ssh服务已经安装。否则可分别使用sudo apt-get install openssh-server
或者sudo yum install openssh-server
安装。
4.检查ssh服务是否启动
在确保ssh服务已经安装的情况下,下面需要检查ssh服务是否已经启动。此时需要注意一点时,在debian系中ssh服务的名称就叫ssh
,在redhat中ssh服务名叫sshd
。
debian系检查ssh服务是否已经启动(注意这里可以看到监听的端口号是0.0.0.0:22
):
如果服务未启动则需要执行sudo service ssh start
来启动ssh服务。
spring@Ubuntu:~$ service ssh status
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-09-08 21:42:37 CST; 10h ago
Main PID: 5203 (sshd)
Tasks: 1 (limit: 3502)
CGroup: /system.slice/ssh.service
└─5203 /usr/sbin/sshd -D
Sep 08 21:42:37 Ubuntu systemd[1]: Starting OpenBSD Secure Shell server...
Sep 08 21:42:37 Ubuntu sshd[5203]: Server listening on 0.0.0.0 port 22.
Sep 08 21:42:37 Ubuntu sshd[5203]: Server listening on :: port 22.
Sep 08 21:42:37 Ubuntu systemd[1]: Started OpenBSD Secure Shell server.
在redhat系中则执行以下命令来检查ssh服务状态(同样可以看到监听的端口号是0.0.0.0:22
):
如果服务未启动则考虑执行sudo service sshd start
。
[spring@localhost ~]$ service sshd status
Redirecting to /bin/systemctl status sshd.service
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-09-08 21:07:10 CST; 11h ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1096 (sshd)
CGroup: /system.slice/sshd.service
└─1096 /usr/sbin/sshd -D
Sep 08 21:07:10 localhost.localdomain systemd[1]: Starting OpenSSH server daemon...
Sep 08 21:07:10 localhost.localdomain sshd[1096]: Server listening on 0.0.0.0 port 22.
Sep 08 21:07:10 localhost.localdomain sshd[1096]: Server listening on :: port 22.
Sep 08 21:07:10 localhost.localdomain systemd[1]: Started OpenSSH server daemon.
较新的Linux发行版本(比如Ubuntu16.04或者CentOS7)开始,均采用systemctl代替service做服务管理。
比如systemctl status ssh
可以检查当前ssh服务状态,使用systemctl start ssh
开启服务。
spring@spring-virtual-machine:~$ systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since 四 2022-06-30 22:20:44 CST; 24h ago Process: 999
ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 994 ExecReload=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Process: 869 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS) Main PID: 878 (sshd) CGroup: /system.slice/ssh.service
└─878 /usr/sbin/sshd -D
5.检查ssh配置文件
其实当走完第四步之后已经能解决大部分的ssh连接问题,但是事实上还是有一些犯罪嫌疑人比较谨慎,下面主要说ssh的主要配置项,一般位于 /etc/ssh/sshd_config
位置。此刻最好加上sudo权限。
#Port 22 # 默认监听端口号是22
#ListenAddress 0.0.0.0 #0.0.0.0代表外网可以连入,如果是127.0.0.0代表只能本机用
#PasswordAuthentication yes
#PermitRootLogin prohibit-password
划重点,从上面我们可以知道默认ssh服务监听在0.0.0.0:22
,这项一般不用修改。
PasswordAuthentication用于表示是否允许以密码的方式验证,有yes
和no
两种值。从运维的角度来说强烈建议改成no
,从技术支持的角度来说强烈建议改成yes
。
重点要讲的是PermitRootLogin。用于表示是否允许root登陆,有以下几种值:yes
, prohibit-password
, without-password
, forced-commands-only
, no
。当值为yes
时,代表允许root以密码验证方式登陆。当值为prohibit-password
或者without-password
时表示允许root登陆但是不允许以密码验证方式,比如可以通过ssh_host_rsa_key
证书方式登陆。当值为forced-commands-only
时表示允许root登陆但是仅能执行指定命令。当值为no
时代表不允许root登陆。从运维的角度来说强烈建议改成no
,从技术支持的角度来说强烈建议改成yes
。
当对上面的值进行修改了之后记得执行sudo service reload sshd
或者sudo service reload ssh
用以生效。
6.检查防火墙
如果认真讲Linux中防火墙的故事可以值得单独写一篇文章,其防火墙经历了iptables->nftables,命令行也产生了眼花缭乱的iptables/ufw/firewall-cmd等。这篇文章并不详细讲述上述故事。在我接触的经验中,只有一次碰到用防火墙拦截ssh端口的事情。犯罪嫌疑人通过iptables禁用了所有连入端口,只开放80的web服务器端口,以及经过nat转发之后的ssh端口。
从技术支持的角度来说,直接sudo /sbin/iptables -F
删除所有规则就好了。
这篇文章对ssh连接linux做了较为详细的总结,应该可以应付大部分的情况。
当然这并不是全部,比如前一期季刊我投稿的《记一次pam后门分析》讲述的pam规则其实也是ssh认证的一环。
总之,linux的学习和实践任重而道远。