ssh连接失败的排错经验

一、场景描述

ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通。

场景:

[root@yl-web ~]# ssh [email protected]
ssh_exchange_identification: read: Connection reset by peer
[root@yl-web ~]# ping 10.1.101.35
PING 10.1.101.35 (10.1.101.35) 56(84) bytes of data.
64 bytes from 10.1.101.35: icmp_seq=1 ttl=64 time=0.587 ms
64 bytes from 10.1.101.35: icmp_seq=2 ttl=64 time=0.722 ms
64 bytes from 10.1.101.35: icmp_seq=3 ttl=64 time=0.475 ms

ping是一个网络层的协议,只是表面网络在3层是通的;

ssh是应用层协议,具体还是从主机上找原因。

二、排错

1、ssh -v

用ssh -v去连有问题的服务器,会有比较详细的调试信息在屏幕上输出,可以帮助判断是哪一步出了问题。

主要是看是客户端还是服务器的问题。如果是客户端的问题,应该log中有写。如果是没有什么有用信息,就可能是服务器端出问题了。

[root@yl-web ~]# ssh -v [email protected]
OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug1: Connecting to 10.1.101.35 [10.1.101.35] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1
ssh_exchange_identification: read: Connection reset by peer

2、连接服务器

现在看起来是服务器出问题了,虽然不能ssh到服务器,但一般来说主机会提供一些方法比去让你连接,比如通过物理终端连进去,具体情况具体对待了,总之就是要连接到服务器上。

3、写一个排错弯路,但也是有用的

如果有debug1: Connection refused by tcp wrapper之类的log可参考这一步。

就是说你的客户端ip可能被服务器给禁掉了,fail2ban或者其他的程序可能把你的客户端ip扔到/etc/hosts.deny中了。

通过vi /etc/hosts.allow查看

未分类

加上一行sshd: ALL。

然后重启ssh。

#service sshd restart

如果问题真的出在ip被禁,这样重启之后应该就ok了。

客户端重新ssh试一下:

[root@yl-web ~]# ssh -v [email protected]
OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug1: Connecting to 10.1.101.35 [10.1.101.35] port 22.
debug1: connect to address 10.1.101.35 port 22: Connection refused
ssh: connect to host 10.1.101.35 port 22: Connection refused

说明我的问题不在这里。

4、两条有用的命令

在服务器上执行下面命令可以显示ssh的所有 log。

centos系统如下:

#service sshd stop
#/usr/sbin/sshd -d

如果是ubuntu可能命令是:

sudo service ssh stop ,sudo /usr/sbin/sshd -d。

未分类

问题出现了: /var/empty/sshd must be owned by root and not group or world-writable。

是权限的问题了,查看一下。

未分类

我的权限变成777了,而sshd这个目录

正常情况该目录的权限应该是:

[root@yl-web ~]# ll /var/empty/
total 0
drwx--x--x. 2 root root 6 May 13 03:41 sshd

修改权限:

未分类

改好权限后重启sshd服务【service sshd restart】。客户端再ssh就ok,大功告成了。

5、命令简介

至此问题已解决,但是/usr/sbin/sshd -d又是什么意思呢?

man sshd看一下这两个参数。

     -D      When this option is specified, sshd will not detach and does not become a daemon.  This allows easy monitoring of sshd.

     -d      Debug mode.  The server sends verbose debug output to standard error, and does not put itself in the background.  The server also will not fork and will only process one connection.  This
             option is only intended for debugging for the server.  Multiple -d options increase the debugging level.  Maximum is 3.

-d是debug模式,服务器会向屏幕输出详细的debug信息,服务器只能有一个ssh链接。

三、题外话

虽然问题解决了,回想一下为什么会出这个问题?因为我昨天在解决一个日志权限的问题时,暴力的将每层目录权限都设置成777,想试探一下是否是目录读写权限的问题,然后再缩小权限,结果影响到了ssh登录。

想想解决一个问题若不能知道原理,很容易放大问题,甚至出现新bug。写代码需谨慎,排错需谨慎,知其然不知其所以然很重要。

Centos系统连接ssh服务器缓慢的解决办法

现象

在机房内网中,用ssh连某台服务器非常慢,基本需要等待15-30秒才会提示让输入密码,但是ping目标机器,延时都是微秒级别,可见并非网络原因造成连接缓慢。

解决办法

方法一

修改本机的客户端配置文件ssh_conf,注意,不是sshd_conf

# vi /etc/ssh/ssh_config

找到:

GSSAPIAuthentication yes

改为:

GSSAPIAuthentication no

保存退出:

# service sshd restart

再连目标机器,速度就飞快了。

解释:GSSAPI ( Generic Security Services Application Programming Interface) 是一套类似Kerberos 5 的通用网络安全系统接口。该接口是对各种不同的客户端服务器安全机制的封装,以消除安全接口的不同,降低编程难度。但该接口在目标机器无域名解析时会有问题。

/etc/ssh/ssh_conf配置实例:

Host    *
GSSAPIAuthentication        no
GSSAPIDelegateCredentials   yes
PasswordAuthentication      yes
RSAAuthentication           yes
StrictHostKeyChecking       no
Port                        22

SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
SendEnv LC_IDENTIFICATION LC_ALL
SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
SendEnv XMODIFIERS

方法二

如果你连接缓慢的目标机器是新添加,那么可以使用本方法,修改目标机器的sshd_conf配置文件

#  vi /etc/ssh/sshd_config

找到:

#UseDNS yes
GSSAPIAuthentication yes

修改为:

UseDNS no
GSSAPIAuthentication no

保存退出

# service sshd restar

然后,我们再使用ssh连接服务器发现速度飞快!

解释:

UseDNS选项来决定是否对远程主机名进行反向解析,以检查此主机名是否与其IP地址真实对应.默认值为”yes”.
如果采用UseDNS yes,客户端登录时,SSH服务端将会打开/etc/hosts,找对映的ip/hostname的解析记录,如果没有找到,这时将会用利用/lib/libnss_dns.so.2动态链接库去/etc/resolv.conf中找DNS服务器做反向解析查询。
如果我们关闭反向解析查询,即UseDNS = no,此时则不会用/etc/host.conf等文件进行hosts/bind反向解析查询,因此会加快连接的速度。

SSH如何反向代理稳定穿透内网

未分类

最近在测试一些站点,总是需要进入到对方内网,而使用的代理工具多为不稳定工具,就连ssh也会断掉,这篇文章分享一下SSH的反向代理,最下面准备啦一个简单的脚本。

0x01 引言

早期我们可能会采用HTTP Proxy代理,在浏览器上设置下代理服务器的IP、端口、认证账户和密码。但有些软件的网络通信数据并不是HTTP协议,就需要寻找其它方法。

SOCKS代理是个不错的解决方案,不管应用层是什么协议,只要是传输层是TCP协议就可以代理。SOCKS代理中最新的协议是SOCKS5。相对SOCKS4作了大幅度的增强。

首先,它增加了对UDP协议的支持;其次,可支持多种用户身份验证方式和通信加密方式;最后,修改了SOCKS服务器进行域名解析的方法,使其更加优雅。

0x02 Socks建立

关于内网的代理工具前人已经总结很多了比如这篇文章内网漫游之SOCKS代理大结局,那我就不多说这些工具了。

稳定SOCKS代理SSH

SSH当之无愧是目前最稳定的代理方式之一,大家用它比较多,但是我们常用的还是他的最简单的转发与正向代理的建立,这里把SSH反向代理分享与大家,不用再为渗透中不稳定的网络而烦恼。

转发

我们常用的是下面的命令,但只能够比较麻烦的访问到已经转发端口上

ssh -CfNg -R 2222:127.0.0.1:22 VPS-user@VPS -p 53 //内网 
ssh -CfNg -L 8080:127.0.0.1:2222 VPS-user@VPS //VPS 本地访问VPS:8080就是内网的22端口
-C:该参数将使ssh压缩所有通过Secure Shell客户端发送的数据,包括输入、输出、错误消息及转发数据。它使用gzip算法,压缩级别可通过设置配制文件中的参数Compressicn Level来指定。这对于缓慢的传输线路特别有用的。但对于传输速度已经很快的网络则显得没有必要。同样,你可以利用配制文件针对每台主机配置这个参数。 
-f:该参数将ssh连接送入后台执行。这在验证已经完成且TCP/IP转发已经建立的情况下会生效。这对在远程主机上启动X程序显得十分重要。其后用户将被提示要求输入口令(提供的认证代理不运行),然后将连接送往后台。 
-g:该参数允许远程主机通过端口转发与主机端口相连,通常情况下仅允许本地主机这样做。 
-N:不执行远程指令。 
-R:远程转发 
-L:本地转发

socks正向代理

下面的方式可以用与你与DMZ区的机器通信,但是如果不能直接访问的内网机器便行不通了。

ssh -qTfnN -D port remotehost
在本地终端中运行 
ssh -qTfnN -D 6080 user@theserver 
然后在浏览器或者软件中设置好代理参数 
socks5: 127.0.0.1:6080 后便可以使用.
-q:静默运行

其实已经很明显了,反向代理就是把上面提到的两个隧道连接在一起,怎么连接呢?

socks反向代理

那么重点来了,如何建立反向代理呢?其实就是把正向代理和转发结合起来即可:

这里为了方便描述,截了几个图,画得丑见笑了…:

未分类

第一步,还是先通过内网机器反向连接VPS:

ssh -p 22 -qngfNTR 6666:localhost:22 VPS-user@VPS

这样就把本地的22端口转发到了远程机器(VPS)的6666端口

查看图中Server机器的进程:

未分类

Server机器转发:

未分类

此时到vps上查看已经在6666端口开始监听了

未分类

第二步,你自己的PC机器直接使用语句:

ssh -p 6666 -qngfNTD 6767 内网用户@VPS

这样就可以直接穿透网络,进入到内网,本地机器直接使用代理127.0.0.1:6767便能够直接访问到内网当中

本地远程访问:

未分类

在Server上开启80端口服务

未分类

配置代理:

未分类

访问:

未分类

进阶配置

那么问题来了,用过SSH的代理的朋友应该知道,我们第一步使用的连接方式在VPS监听的6666端口应该是监听在localhost上的,那么在第一步之前就应该修改一些配置了:在VPS的ssh配置当中加入如下配置GatewayPorts yes,这里是指远程转发过来的端口监听在0.0.0.0上。当然也可以你再在VPS本地转发一次即可。

这样就完了吗?当然没有,经过测试,我们是无法让这个代理保持一直在线的,SSH在一定时间没有任何的操作后就会自动的断开,那么我们同样再次修改配置文件:

找到 ClientAliveInterval 0和ClientAliveCountMax 3并将注释符号(”#”)去掉, 将ClientAliveInterval对应的0改成60,ClientAliveInterval指定了服务器端向客户端请求消息的时间间隔, 默认是0,不发送. ClientAliveInterval 60表示每分钟发送一次, 然后客户端响应, 这样就保持长连接了. ClientAliveCountMax, 使用默认值3即可.ClientAliveCountMax表示服务器发出请求后客户端没有响应的次数达到一定值, 就自动断开. 这样的配置就能让一个SSH的配置保持长连接了,代理就能稳定的在线。那么这样是需要每次都输入密码而且每次输入一大堆命令很麻烦,这里写了一个简单的CentOS上使用脚本来开启代理。

#!/usr/bin/env bash
#author: rootclay
export HISTSIZE=0
#install
cd /etc/yum.repos.d/ 
wget http://download.opensuse.org/repositories/home:Strahlex/CentOS_CentOS-6/home:Strahlex.repo 
yum install -y sshpass 
yum install -y screen
mkdir /tmp/mongo && chown $(whoami):$(whoami) /tmp/mongo 
sudo tee /tmp/mongo/daemon.sh <<-'EOF'

#!/usr/bin/env bash
while: 
do 
    /usr/bin/sshpass -p 你的VPS密码 ssh -p 22 -qngfNTR 6770:localhost:22 
    VPS-user@VPS -o StrictHostKeyChecking=no 
    sleep 18000 
    ps -ef | grep qngfNTR | awk '{print $2}' | xargs kill -9 
done 
EOF

chmod +x /tmp/mongo/daemon.sh 
echo "screen -dmS test /tmp/mongo/daemon.sh" >> /etc/rc.d/rc.local 
screen -dmS socks /tmp/mongo/daemon.sh 
useradd test;echo 'test:1234' | chpasswd
/usr/local/bin/sshpass -p "1234" ssh -p 6770 -qngfNTD 6770 test@VPS -o 
StrictHostKeyChecking=no 
本地执行执行这条命令即可,代理设置为127.0.0.1:6770即可进入内网

这样建立起来的socks网络是非常的稳定的,搭建了之后可以试一试开扫描器扫一扫,高线程都不会掉。。。而前面使用的比如EW之类的。。。一扫就挂=。=,这个开个高线程完全没问题。

利用denyhosts防止服务器被ssh暴力破解

博主我新买的VPS建站没几天,心想应该没人动我的歪主意就一直没太注意服务器安全。今天用iftop查看到有几个IP一直连接中,而我的blog里的流量统计页面访问数量却没有新增,很明显这不是在访问blog。通过netstat -anp 可以查看到这几个IP,尤其有个IP还不断更换端口一直尝试访问我的22端口,能用22端口无非是ssh终端连接。心里一想百分百99%是尝试暴力破解,事不宜迟赶紧封锁。

未分类

一查乌克兰的,还不能ping它,也就是说单向访问

未分类

通过iftop能实时查看流量连接情况

未分类

tail -f /var/log/secure 可以查看ssh登陆失败的信息,证实了193.201.224.199这家伙在尝试暴力破解

利用denyhosts 防止暴力破解ssh

DenyHosts是Python语言写的一个程序,它会分析sshd的日志文件(/var/log/secure),当发现重 复的攻击时就会记录IP到/etc/hosts.deny文件,从而达到自动屏IP的功能。

思路:利用读取到/var/log/secure登陆失败的IP信息,我们可以设定一个规则,如果登陆失败超过多少次,我们把这个IP写到 /etc/hosts.deny中,拒绝访问!

1、先把始终允许的IP填入 /etc/hosts.allow ,因为自己访问超过了次数那就尴尬了。不过一般购买的VPS都有后台可以更改ROOT登陆密码,所以这个步骤也可以不设置。

# vim /etc/hosts.allow
   # sshd:IP:allow

2、安装DenyHosts 官方网站为:http://denyhosts.sourceforge.net

# tar -zxvf DenyHosts-2.6.tar.gz
# cd DenyHosts-2.6
# python setup.py install 

3、配置

# cd /usr/share/denyhosts/ 
# cp denyhosts.cfg-dist denyhosts.cfg 
# vi denyhosts.cfg
SECURE_LOG = /var/log/secure  #要读取安全日志路径,默认的不管它
HOSTS_DENY = /etc/hosts.deny #将阻止IP写入到hosts.deny,默认的不管它
PURGE_DENY = 1d #设定过多久后清除已阻止IP (m=分钟,h=小时,d=天,w=周)
BLOCK_SERVICE = sshd #阻止服务名
DENY_THRESHOLD_INVALID = 5 #允许无效用户登录失败的次数
DENY_THRESHOLD_VALID = 10 #允许普通用户登录失败的次数
DENY_THRESHOLD_ROOT = 3 #允许root登录失败的次数
(上面3个登陆失败的次数建议不要设定太苛刻,以免自己输错了被列入黑名单了)
DENY_THRESHOLD_RESTRICTED = 1 #设定 deny host 写入到该资料夹
WORK_DIR = /usr/local/share/denyhosts/data #将deny的host或ip纪录到Work_dir中
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES #假如设定为YES,那么已经设为白名单中的IP登陆失败也会被设为可疑,也会被列入黑名单中,设定NO的意思就相反。
HOSTNAME_LOOKUP=YES #如果可以的话记录登陆失败的hostname
LOCK_FILE = /var/lock/subsys/denyhosts #将DenyHOts启动的pid纪录到LOCK_FILE中,已确保服务正确启动,防止同时启动多个服务。 
HOSTNAME_LOOKUP=NO #是否做域名反解 
ADMIN_EMAIL = #设置管理员邮件地址 
DAEMON_LOG = /var/log/denyhosts #自己的日志文件 
DAEMON_PURGE = 10m #该项与PURGE_DENY 设置成一样,也是清除hosts.deniedssh 用户的时间。 

4、设置启动脚本

# cp daemon-control-dist daemon-control
# chown root daemon-control
# chmod 700 daemon-control
完了之后执行daemon-contron start就可以了。
# ./daemon-control start
如果要使DenyHosts每次重起后自动启动还需做如下设置:
# ln -s /usr/share/denyhosts/daemon-control /etc/init.d/denyhosts
# chkconfig –add denyhosts
# chkconfig denyhosts on

然后就可以启动了:

# service denyhosts start
# ps -ef|grep denyhosts #检查是否启动

未分类

 # vim /etc/hosts.deny #查看内是否有禁止的IP,有的话说明已经成功了。

未分类

ubuntu安装openssh启用SSH登录服务器

默认情况下,ubuntu系统在安装完成之后,不会安装openssh相关的软件包,所有我们在远程ssh登录到ubuntu系统的时候会失败。

本文将会讲述如何来安装openssh相关软件包来解决无法远程ssh登录到ubuntu系统的问题。

1、执行下面的apt-get命令安装openssh相关软件包。

apt-get install openssh*

ubuntutest@ubuntutest:~$ apt-get install openssh*
E: 无法打开锁文件 /var/lib/dpkg/lock - open (13: Permission denied)
E: 无法对状态列表目录加锁(/var/lib/dpkg/),请查看您是否正以 root 用户运行?
ubuntutest@ubuntutest:~$ sudo apt-get install openssh*
[sudo] password for ubuntutest:
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
注意,根据Glob 'openssh*' 选中了 'openssh-known-hosts'
注意,根据Glob 'openssh*' 选中了 'openssh-blacklist-extra'
注意,根据Glob 'openssh*' 选中了 'openssh-blacklist'
注意,根据Glob 'openssh*' 选中了 'openssh-sftp-server'
注意,根据Glob 'openssh*' 选中了 'openssh-server'
注意,根据Glob 'openssh*' 选中了 'openssh-client'
注意,根据Glob 'openssh*' 选中了 'openssh-client-ssh1'
openssh-blacklist 已经是最新版 (0.4.1+nmu1)。
openssh-blacklist-extra 已经是最新版 (0.4.1+nmu1)。
openssh-known-hosts 已经是最新版 (0.6.2-1)。
openssh-client 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-server 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-sftp-server 已经是最新版 (1:7.2p2-4ubuntu2.2)。
openssh-client-ssh1 已经是最新版 (1:7.2p2-4ubuntu2.2)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 128 个软件包未被升级。

2、查看sshd 服务是否启动,执行下面的命令

ps aux | grep sshd

ubuntutest@ubuntutest:~$ ps aux | grep sshd
root      1129  0.0  0.2  65520  5272 ?        Ss   10:23   0:00 /usr/sbin/sshd -D
root      1304  0.0  0.3  95400  7012 ?        Ss   10:24   0:00 sshd: root@pts/0

3、使用非root 用户来验证是否能够SSH远程登录到该Ubuntu系统

ubuntutest@ubuntutest:~$ ssh ubuntutest@localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:gy+Rueth1RoavXu2zvs230nZUiCSRIcQZvivSDixfn4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ubuntutest@localhost's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

128 个可升级软件包。
62 个安全更新。

Last login: Wed Aug  2 10:11:14 2017
ubuntutest@ubuntutest:~$

CentOS 7修改SSH端口并配置iptables防火墙

摘要

昨天我连接 ssh 的时候看到,有 600 多次来自某个阿里云服务器的失败登录,然后赶紧改了密码,顺便再改一下 ssh 的允许端口……万万没想到,网上搜到的大部分教程均不能生效。在找了几个关键信息后得到比较完全的 CentOS 7 SSH 端口修改步骤。

修改 sshd_config 端口

$ vi /etc/ssh/sshd_config

取消 #Port 22 的注释,在下一行添加你需要修改的新端口 Port 2048。(这里不删除 22 端口是为了防止修改后新端口无法访问,造成无法用 ssh 连接服务器。)

Port 22  
Port 2048  

修改保存 sshd_config 文件后重启 sshd 服务:

$  systemctl restart sshd

退出 ssh 会话后,再用新的端口连接:

$ ssh -p 2048 [email protected]
ssh: connect to host 0.0.0.0 port 2048: Connection refused  

好吧,native 了……对于 CentOS 7 这一套修改端口的方法已经不能生效了。

打开 SELinux 端口

SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。

对于 ssh,SELinux 默认只允许 22 端口,我们可以用 SELinux 管理配置工具 semanage,来修改 ssh 可访问的端口。

安装 semanage 工具

$ yum provides semanage
$ yum -y install policycoreutils-python

为 ssh 打开 2048 端口

# 为 ssh 添加新的允许端口
$ semanage port -a -t ssh_port_t -p tcp 2048
# 查看当前 SELinux 允许的端口
$ semanage port -l | grep ssh
ssh_port_t                     tcp      2048, 22  

错误处理

当 SELINUX 配置为禁用状态时,使用 semanage 会报错提示无法读取 policy 文件:

SELinux:  Could not downgrade policy file /etc/selinux/targeted/policy/policy.30, searching for an older version.  
SELinux:  Could not open policy file <= /etc/selinux/targeted/policy/policy.30:  No such file or directory  
/sbin/load_policy:  Can't load policy:  No such file or directory
libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory).  
FileNotFoundError: [Errno 2] No such file or directory  

修改 /etc/selinux/config 配置,启用 SELinux:

$ vi /etc/selinux/config
SELINUX=permissive  
# 重启服务器
$ init 6
# 重启后查看 SELinux 状态
$ sestatus
# if it shows disable, you can run
$ load_policy -qi

检查配置

$ semanage port -a -t ssh_port_t -p tcp 2048
$ semanage port -l | grep ssh
ssh_port_t                     tcp      2048, 22  
# 重启 ssh 服务
systemctl restart sshd  

注:semange 不能禁用 ssh 的 22 端口:

$ semanage port -d -t ssh_port_t -p tcp 22
ValueError: 在策略中定义了端口 tcp/22,无法删除。  

配置防火墙 firewalld

启用防火墙 && 查看防火墙状态

$ systemctl enable firewalld
$ systemctl start firewalld
$ systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since 二 2016-12-20 02:12:59 CST; 1 day 13h ago
 Main PID: 10379 (firewalld)
   CGroup: /system.slice/firewalld.service
           └─10379 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
$ firewall-cmd --state
running  

查看防火墙当前「默认」和「激活」zone(区域)

$ firewall-cmd --get-default-zone
public  
$ firewall-cmd --get-active-zones
public  
  interfaces: eth0 eth1

若没有激活区域的话,要执行下面的命令。

激活 public 区域,增加网卡接口

$ firewall-cmd --set-default-zone=public
$ firewall-cmd --zone=public --add-interface=eth0
success  
$ firewall-cmd --zone=public --add-interface=eth1
success  

为 public zone 永久开放 2048/TCP 端口:

# 以防新端口不生效,先把 22 端口暴露
$ firewall-cmd --permanent --zone=public --add-port=22/tcp
$ firewall-cmd --permanent --zone=public --add-port=2048/tcp
success  
# 重载防火墙
$ firewall-cmd --reload
# 查看暴露端口规则
$ firewall-cmd --permanent --list-port
443/tcp 80/tcp 22/tcp 2048/tcp  
$ firewall-cmd --zone=public --list-all
public (default, active)  
  interfaces: eth0 eth1
  sources:
  services: dhcpv6-client ssh
  ports: 443/tcp 80/tcp 22/tcp 2048/tcp
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

退出 ssh 后,尝试连接新端口

$ ssh -p 2048 [email protected]

成功登录的话,就可以做收尾工作了。

禁用 22 端口

删除 ssh 允许端口

$ vi /etc/ssh/sshd_config
#Port 22
Port 2048  
$ systemctl restart sshd
# 用 ss 命令检查 ssh 监听的端口,没有 22 证明修改成功
$ ss -tnlp | grep ssh
LISTEN     0      128                       *:2048                    *:*      users:(("sshd",18233,3))  

防火墙移除 22 端口

$ firewall-cmd --permanent --zone=public --remove-port=22/tcp
success  
$ firewall-cmd --reload
$ firewall-cmd --permanent --list-port
443/tcp 80/tcp 2048/tcp  

ssh 取消监听 22 端口,就已经配置好了,防火墙只不过是在 ssh 外多一层访问限制。如果要做的更好还可以将 22 端口的访问流量转向访问者本地:

$ firewall-cmd --permanen --zone=public --add-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1
# 配置后重载防火墙,用 ssh -p 22 [email protected] 就会访问到自己本地的 22 端口。

若要删除 forward 配置,可以:

$ firewall-cmd --permanen --zone=public --remove-forward-port=port=22:proto=tcp:toport=22:toaddr=127.0.0.1

检验修改 ssh 端口是否成功:

$ ssh -p 22 [email protected]
# 无响应,因为转到了本地的 22 端口
# 若防火墙未 forward 连接,则会回显 "ssh: connect to host {ip} port 22: Connection refused"
$ ssh -p 2048 [email protected]
# 成功 success

修复使用证书无法ssh登录服务器的问题

引入

服务器一直 ssh 登录正常,突然有段时间发现不能登录了,查看原因

从客户端查看

ssh -v user@host

查看过后,发现问题不在客户端上面

从服务器上查找原因

首先查看 .ssh 目录 和 authorized_keys 的权限

.ssh 为 700,authorized_keys 为 600,正常

查看日志

tailf /var/log/secure

返回结果

Authentication refused: bad ownership or modes for directory /root

查看 root 文件夹权限

发现文件夹被改成了 777,改回 755 即可正常登录

CentOS-6修改ssh端口并配置密钥登录

1、导入客户端密钥

$> vi ~/.ssh/authorized_keys #没有就新建
(复制客户端 ~/.ssh/id_rsa.pub 保存文件)
$> chmod 700 ~/.ssh/authorized_keys

2、禁止使用密码登录

$> vi /etc/ssh/sshd_config
修改为: PasswordAuthentication No 

3、修改默认端口

$> vi /etc/ssh/sshd_config
修改为: Port 11233
$> service sshd restart

4、开放端口防火墙权限

$> iptables -I INPUT 4 -p tcp -m state --state NEW -m tcp --dport 11233  -j ACCEPT
$> service iptables save

校验方式:客户端链接方式:

$> ssh [email protected] -p 11233

配置ssh密钥登录(无需密码)

配置密钥可使用户免密ssh方式登录服务器。

配置方法:

生成密钥对

$ ssh-keygen

此处可选择生成密钥的文件路径,默认为~/.ssh/id_rsa
密码为可选。

拷贝公钥到服务器

方式一:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub xxx@host

方式二:

手动拷贝id_rsa.pub到服务器上,并收到添加认证文件。

$ cat id_rsa.pub >> ~/.ssh/authorized_keys

服务器配置

配置服务器上/etc/ssh/sshd_config文件,修改以下配置项

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile  .ssh/authorized_keys

修改后,重启sshd服务,根据不同的系统使用相应命令

登录

直接登录

$ ssh user@host

如果配置成功,则不需要密码直接登录。

问题

配置成功后,仍提示密码输入

主要原因在于服务器上认证文件及所在目录的权限问题

详情排查步骤可查看文章配置ssh公钥登录提示还是输入密码

解决方法:

$ chmod 755 ~/home/xxxuser

解决ssh登录时很慢的问题

使用ssh客户端(如:putty)连接Linux服务器,可能会等待10-30秒才有提示输入密码。严重影响工作效率。登录很慢,登录上去后速度正常,这种情况主要有两种可能的原因:

1、 DNS反向解析问题

OpenSSH在用户登录的时候会验证IP,它根据用户的IP使用反向DNS找到主机名,再使用DNS找到IP地址,最后匹配一下登录的IP是否合法。如果客户机的IP没有域名,或者DNS服务器很慢或不通,那么登录就会很花时间。

解决办法:在目标服务器上修改sshd服务器端配置,并重启sshd

vi /etc/ssh/sshd_config
UseDNS no

2、 关闭ssh的gssapi认证

用ssh -v user@server 可以看到登录时有如下信息:

debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information

注:ssh -vvv user@server 可以看到更细的debug信息

解决办法:

修改sshd服务器端配置

vi /etc/ssh/ssh_config
GSSAPIAuthentication no

可以使用ssh -o GSSAPIAuthentication=no user@server登录

GSSAPI ( Generic Security Services Application Programming Interface) 是一套类似Kerberos 5的通用网络安全系统接口。该接口是对各种不同的客户端服务器安全机制的封装,以消除安全接口的不同,降低编程难度。但该接口在目标机器无域名解析时会有 问题

使用strace查看后发现,ssh在验证完key之后,进行authentication gssapi-with-mic,此时先去连接DNS服务器,在这之后会进行其他操作

[root@192-168-3-40 ~]# ssh -vvv [email protected]  
OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013  
debug1: Reading configuration data /etc/ssh/ssh_config  
debug1: Applying options for *  
debug2: ssh_connect: needpriv 0  
debug1: Connecting to 192.168.3.44 [192.168.3.44] port 22.  
debug1: Connection established.  
debug1: permanently_set_uid: 0/0  
debug1: identity file /root/.ssh/identity type -1  
debug1: identity file /root/.ssh/identity-cert type -1  
debug1: identity file /root/.ssh/id_rsa type -1  
debug1: identity file /root/.ssh/id_rsa-cert type -1  
debug1: identity file /root/.ssh/id_dsa type -1  
debug1: identity file /root/.ssh/id_dsa-cert type -1  
debug1: identity file /root/.ssh/id_ecdsa type -1  
debug1: identity file /root/.ssh/id_ecdsa-cert type -1  
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3  
debug1: match: OpenSSH_5.3 pat OpenSSH*  
debug1: Enabling compatibility mode for protocol 2.0  
debug1: Local version string SSH-2.0-OpenSSH_5.3  
debug2: fd 3 setting O_NONBLOCK  
debug1: SSH2_MSG_KEXINIT sent  
debug3: Wrote 960 bytes for a total of 981  
debug1: SSH2_MSG_KEXINIT received  
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1  
debug2: kex_parse_kexinit: [email protected],[email protected],[email protected],[email protected],ssh-rsa,ssh-dss  
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]  
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]  
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96  
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96  
debug2: kex_parse_kexinit: none,[email protected],zlib  
debug2: kex_parse_kexinit: none,[email protected],zlib  
debug2: kex_parse_kexinit:  
debug2: kex_parse_kexinit:  
debug2: kex_parse_kexinit: first_kex_follows 0  
debug2: kex_parse_kexinit: reserved 0  
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1  
debug2: kex_parse_kexinit: ssh-rsa,ssh-dss  
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]  
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,[email protected]  
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96  
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,[email protected],hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96  
debug2: kex_parse_kexinit: none,[email protected]  
debug2: kex_parse_kexinit: none,[email protected]  
debug2: kex_parse_kexinit:  
debug2: kex_parse_kexinit:  
debug2: kex_parse_kexinit: first_kex_follows 0  
debug2: kex_parse_kexinit: reserved 0  
debug2: mac_setup: found hmac-md5
debug1: kex: server->client aes128-ctr hmac-md5 none  
debug2: mac_setup: found hmac-md5  
debug1: kex: client->server aes128-ctr hmac-md5 none  
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent  
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP  
debug3: Wrote 24 bytes for a total of 1005  
debug2: dh_gen_key: priv key bits set: 120/256  
debug2: bits set: 506/1024  
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent  
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY  
debug3: Wrote 144 bytes for a total of 1149  
debug3: check_host_in_hostfile: host 192.168.3.44 filename /root/.ssh/known_hosts  
debug3: check_host_in_hostfile: host 192.168.3.44 filename /root/.ssh/known_hosts  
debug3: check_host_in_hostfile: match line 8  
debug1: Host '192.168.3.44' is known and matches the RSA host key.  
debug1: Found key in /root/.ssh/known_hosts:8  
debug2: bits set: 527/1024  
debug1: ssh_rsa_verify: signature correct  
debug2: kex_derive_keys  
debug2: set_newkeys: mode 1  
debug1: SSH2_MSG_NEWKEYS sent  
debug1: expecting SSH2_MSG_NEWKEYS  
debug3: Wrote 16 bytes for a total of 1165  
debug2: set_newkeys: mode 0  
debug1: SSH2_MSG_NEWKEYS received  
debug1: SSH2_MSG_SERVICE_REQUEST sent  
debug3: Wrote 48 bytes for a total of 1213  
debug2: service_accept: ssh-userauth  
debug1: SSH2_MSG_SERVICE_ACCEPT received  
debug2: key: /root/.ssh/identity ((nil))  
debug2: key: /root/.ssh/id_rsa ((nil))  
debug2: key: /root/.ssh/id_dsa ((nil))  
debug2: key: /root/.ssh/id_ecdsa ((nil))  
debug3: Wrote 64 bytes for a total of 1277  
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password  
debug3: start over, passed a different list publickey,gssapi-keyex,gssapi-with-mic,password  
debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password  
debug3: authmethod_lookup gssapi-keyex  
debug3: remaining preferred: gssapi-with-mic,publickey,keyboard-interactive,password  
debug3: authmethod_is_enabled gssapi-keyex  
debug1: Next authentication method: gssapi-keyex  
debug1: No valid Key exchange context  
debug2: we did not send a packet, disable method  
debug3: authmethod_lookup gssapi-with-mic  
debug3: remaining preferred: publickey,keyboard-interactive,password  
debug3: authmethod_is_enabled gssapi-with-mic  
debug1: Next authentication method: gssapi-with-mic  
debug3: Trying to reverse map address 192.168.3.44.  
debug1: Unspecified GSS failure.  Minor code may provide more information  
Cannot determine realm for numeric host address  

debug1: Unspecified GSS failure.  Minor code may provide more information  
Cannot determine realm for numeric host address  

debug1: Unspecified GSS failure.  Minor code may provide more information  


debug1: Unspecified GSS failure.  Minor code may provide more information  
Cannot determine realm for numeric host address  

debug2: we did not send a packet, disable method  
debug3: authmethod_lookup publickey  
debug3: remaining preferred: keyboard-interactive,password  
debug3: authmethod_is_enabled publickey  
debug1: Next authentication method: publickey  
debug1: Trying private key: /root/.ssh/identity  
debug3: no such identity: /root/.ssh/identity  
debug1: Trying private key: /root/.ssh/id_rsa  
debug3: no such identity: /root/.ssh/id_rsa  
debug1: Trying private key: /root/.ssh/id_dsa  
debug3: no such identity: /root/.ssh/id_dsa  
debug1: Trying private key: /root/.ssh/id_ecdsa  
debug3: no such identity: /root/.ssh/id_ecdsa  
debug2: we did not send a packet, disable method  
debug3: authmethod_lookup password  
debug3: remaining preferred: ,password  
debug3: authmethod_is_enabled password  
debug1: Next authentication method: password  
[email protected]'s password: