ssh 隐藏版本号

在openssh的源码文件中。

出现有一个sshd.c的文件,用vi sshd.c打开这个文件,找到这一条语句:

snprintf(buf, sizeof buf, “SSH-%d.%d-%.100sn”, major, minor, SSH_VERSION);

将其修改成:

snprintf(buf, sizeof buf, “goodbye”);

然后再使用下面使命令安装openssh

./configure -prefix=/opt/ssh -sysconfdir=/etc/ssh
make
make install

安装完成之后,执行下面命令:

/opt/ssh/sbin/sshd

然后,你在其他机器上使用如下命令:

telnet SSH服务器IP地址 22

此时就只显示goodbye啦。

以上操作在Redhat EL AS4中测试过,不过在安装openssh时需要一些库文件支持,以上只是个人的做法,仅供参考。

将尝试SSH爆破的IP批量添加到hosts.deny

如果有人尝试爆破ssh服务,就会在 /var/log/secure留下错误记录,因此我们可以利用下面的脚本批量添加历史IP到/etc/hosts.deny

#!/bin/bash

#add ip ban list and log the first 1000 lines
#grep "Failed password for invalid user" /var/log/secure | awk '{print $13}' | sort | uniq -c | sort -nr | head -n 1000|
#add invalid user ban list and log the first 100 lines
grep "Failed password for invalid user" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr|head -n 100|

while read a b  
do  
    grep -q $b /etc/hosts.deny
      if [ $? != 0 ] ; then
        if [ $a -ge 5 ] ; then
            echo "sshd: $b" >> /etc/hosts.deny
            fi
      fi
done

使用python 实现自动登录ssh

介绍

本文介绍使用python 自动连ssh,并通过正则处理返回值。

通过这段代码,可以使一些繁杂的工作,变成比较简单以及自动化。

代码

#!/usr/bin/env python

import pexpect
import signal, fcntl, termios, struct, sys

global_pexpect_instance = None

# 当窗口大小有改变时
def sigwinch_passthrough(sig, data):
    # Set terminal size
    if 'TIOCGWINSZ' in dir(termios):
        TIOCGWINSZ = termios.TIOCGWINSZ
    else:
        TIOCGWINSZ = 1074295912
    s = struct.pack ("HHHH", 0, 0, 0, 0)
    a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
    global global_pexpect_instance
    global_pexpect_instance.setwinsize(a[0],a[1])

# 处理返回值,并输入密码
def ssh_password(child,password,other=None):
    global base_path
    ssh_newkey = 'Are you sure you want to continue connecting'
    while True:
        step=[pexpect.TIMEOUT, ssh_newkey, '[pP]assword:.*', '.*[$#] '];
        if other:
            step.append(other);
        i = child.expect(step,timeout=120)
        print "expect:"+step[i];
        if i == 0:
            print child.before,child.befor
            print child.before,child.after
            print 'Time out'
            return False;
        if i == 1:
            child.sendline('yes')
        if i == 2:
            child.sendline(password)
        if i == 3:
            print child.before,child.after
            return True;
    return True;

# 发送命令
def ssh_command(host, user, password, post_command=None):
    global global_pexpect_instance
    print 'ssh -l %s %s'%(user, host);
    child = pexpect.spawn('ssh -l %s %s'%(user, host))
    global_pexpect_instance = child
    signal.signal(signal.SIGWINCH, sigwinch_passthrough)
    if not ssh_password(child,password):
        return None;
    if post_command :
        child.sendline(post_command);
    return child;
# 等待返回,当非字符交互界面时用:如执行命令,等待结束
def ssh_wait(child,other=None):
    step=[pexpect.TIMEOUT,    '.*[$#]'];
    if other:
        step.append(other);
    i = child.expect(step)
    print child.before
    print child.after

# 执行远程登录,如果有命令则直接返回,如果不是执行命令,则进入字符交互界面
def ssh(host,user,password,post_command=None):
    child=ssh_command(host,user,password,post_command)
    sigwinch_passthrough(None, None)
    if child==None:
        return
    if post_command==None:
        child.interact(chr(0x1e)) # ctrl+~
    else:
        ssh_wait(child)

解释

主要思路:

第一步: pexpect 包的spawn 执行ssh 并将用户名和地址填上

第二步:spawn会返回子进程的句柄,通过这个句柄,可以进行发送以及接收返回的字符串

第三步:使用 expect 函数,对返回进行正则匹配

第四步:

expect,会返回命中规则的下标,然后,可以对各种情况进行处理.

比如,在返回 ‘[pP]assword:.*’ 时,发送密码

第五步:

最后,调用interact 进入字符交互界面。然后,就可以手动输入其他命令了。

总结

有了这套工具,可以实现快捷地登录服务器,或者是以另外一种鉴权方式登录服务器(如短信)

比如,我当前的使用是,快捷登录,比如输入 myssh cmky 就可以登录我的服务器了。

相当方便,如果使用linux 还可以和tmux 一同工作。

番外篇:与tmux 一同工作

我们将以上脚本保存为一个叫myssh 的可执行文件,并保存在可执行目录下

我们添加一个脚本,叫tssh :

echo $1
ifattach=0;
tmux -L `whoami` list-sessions
if [[ $? -ne 0 ]]; then
    echo "mytmux";
    ifattach=1;
    tmux -L `whoami` new -d
fi
tmux -L `whoami` neww -n $1 "myssh $1"

if [[ $ifattach -eq 1 ]]; then
    echo "attach"
    tmux -L `whoami` attach
fi

之所以添加 -L whoami 是为了避免在多用户下,公用tmux 而产生的问题。

保证每个用户一个tmux 服务

注意替换 myssh $1 为你自己的命令。

Linux VPS上DenyHosts阻止SSH暴力攻击

现在的互联网非常不安全,很多人没事就拿一些扫描机扫描ssh端口,然后试图连接ssh端口进行暴力破解(穷举扫描),所以建议vps主机的空间,尽量设置复杂的ssh登录密码,虽然在前段时间曾经介绍过Linux VPS禁止某个IP访问使用hosts.deny禁止某些IP访问,但是功能方面欠缺,如:不能自动屏蔽,那么有什么更好的办法吗,就可以使用denyhosts这款软件了,它会分析/var/log/secure(redhat,Fedora Core)等日志文件,当发现同一IP在进行多次SSH密码尝试时就会记录IP到/etc/hosts.deny文件,从而达到自动屏蔽该IP的目的。

DenyHosts官方网站为:http://denyhosts.sourceforge.net/

LNMP一件安装包中自带该软件可以一键安装,命令:

wget http://soft.vpser.net/lnmp/lnmp1.4beta.tar.gz && tar zxf lnmp1.4beta.tar.gz && cd lnmp1.4/tools/ && ./denyhosts.sh 

回车确认即可开始安装配置,不需要下面的步骤进行安装配置。(该tools目录下也有denyhosts相似的工具fail2ban的一键安装工具 ./fail2ban.sh 安装即可)

1、下载DenyHosts 并解压

# wget http://soft.vpser.net/security/denyhosts/DenyHosts-2.6.tar.gz
# tar zxvf DenyHosts-2.6.tar.gz
# cd DenyHosts-2.6

2、安装、配置和启动

安装前建议执行:echo “” > /var/log/secure && service rsyslog restart 清空以前的日志并重启一下rsyslog

# python setup.py install

因为DenyHosts是基于python的,所以要已安装python,大部分Linux发行版一般都有。默认是安装到/usr/share/denyhosts/目录的,进入相应的目录修改配置文件

# cd /usr/share/denyhosts/
# cp denyhosts.cfg-dist denyhosts.cfg
# cp daemon-control-dist daemon-control

默认的设置已经可以适合centos系统环境,你们可以使用vi命令查看一下denyhosts.cfg和daemon-control,里面有详细的解释

接着使用下面命令启动denyhosts程序

# chown root daemon-control
# chmod 700 daemon-control
# ./daemon-control start

如果要使DenyHosts每次重起后自动启动还需做如下设置:

# ln -sf /usr/share/denyhosts/daemon-control /etc/init.d/denyhosts
# chkconfig –add denyhosts
# chkconfig –level 2345 denyhosts on

或者执行下面的命令加入开机启动,将会修改/etc/rc.local文件:

# echo “/usr/share/denyhosts/daemon-control start” >> /etc/rc.local

DenyHosts配置文件/usr/share/denyhosts/denyhosts.cfg说明:

SECURE_LOG = /var/log/secure
#sshd日志文件,它是根据这个文件来判断的,不同的操作系统,文件名稍有不同。

HOSTS_DENY = /etc/hosts.deny
#控制用户登陆的文件

PURGE_DENY = 5m
DAEMON_PURGE = 5m
#过多久后清除已经禁止的IP,如5m(5分钟)、5h(5小时)、5d(5天)、5w(5周)、1y(一年)

BLOCK_SERVICE  = sshd
#禁止的服务名,可以只限制不允许访问ssh服务,也可以选择ALL

DENY_THRESHOLD_INVALID = 5
#允许无效用户失败的次数

DENY_THRESHOLD_VALID = 10
#允许普通用户登陆失败的次数

DENY_THRESHOLD_ROOT = 5
#允许root登陆失败的次数

HOSTNAME_LOOKUP=NO
#是否做域名反解

DAEMON_LOG = /var/log/denyhosts

为防止自己的IP被屏蔽,可以:echo “你的IP” >> /usr/share/denyhosts/allowed-hosts 将你的IP加入白名单,再重启DenyHosts:/etc/init.d/denyhosts ,如果已经被封,需要先按下面的命令删除被封IP后再加白名单。

如有IP被误封,可以执行下面的命令解封:

wget http://soft.vpser.net/security/denyhosts/denyhosts_removeip.sh && bash denyhost_removeip.sh 要解封的IP

更多的说明请查看自带的README文本文件,好了以后维护VPS就会省一些心了,但是各位VPSer们注意了安全都是相对的哦,没有绝对安全,将密码设置的更Strong,并请定期或不定期的检查你的VPS主机,而且要定时备份你的数据哦。

与DenyHosts类似的软件还有fail2ban功能上更多,还可以对ftp进行保护,自己可以搜索看一下。

如何使用Google身份验证器双重身份验证来保护SSH

未分类

要使用易于使用的双因素认证来保护您的SSH服务器? Google提供必要的软件,可将Google Authenticator的基于时间的一次性密码(TOTP)系统与您的SSH服务器相集成。当您连接时,您必须从手机输入代码。

Google身份验证器不会向Google“回家”事实上,Google Authenticator是完全开源的,所以你甚至可以自己检查它的源代码。

安装Google Authenticator

要使用Google Authenticator实施多因素身份验证,我们需要开源的Google Authenticator PAM模块。PAM代表“可插拔认证模块” – 它可以轻松地将不同形式的认证插入到Linux系统中。

Ubuntu的软件仓库包含一个易于安装的Google Authenticator PAM模块软件包。如果您的Linux发行版不包含该软件包,则必须从Google Code的Google Authenticator下载页面下载该文件并自行编译。

要在Ubuntu上安装软件包,请运行以下命令:

sudo apt-get install libpam-google-authenticator

(这将仅在我们的系统上安装PAM模块 – 我们必须手动激活SSH登录。)

未分类

创建验证密钥

作为您将远程登录的用户登录,并运行google-authenticator命令为该用户创建一个密钥。

通过输入y可以使命令更新您的Google Authenticator文件。然后会提示您提出几个问题,这些问题将允许您限制使用相同的临时安全性令牌,增加令牌可以使用的时间窗口,并限制允许的访问次数来阻止暴力破解尝试。这些选择都为一些易于使用的交易提供了一些安全保障。

未分类

Google Authenticator将向您显示一个秘密密钥和几个“紧急划痕代码”。“将紧急划痕代码写在一个安全的地方 – 它们只能使用一次,如果您丢失手机,它们将被用于使用。

未分类

在您手机上的Google Authenticator应用程式中输入密码(官方应用程式适用于Android,iOS和Blackberry)。您还可以使用扫描条形码功能 – 转到位于命令输出顶部附近的URL,您可以使用手机的相机扫描QR码。

未分类

您的手机上的验证码不断变化。

未分类

如果要作为多个用户远程登录,请为每个用户运行此命令。每个用户将拥有自己的秘密密钥和自己的密码。

激活Google身份验证器

下一步您将不得不要求Google Authenticator进行SSH登录。为此,请打开/ etc / pam。您的系统上的d / sshd文件(例如,使用sudo nano / etc / pam)d / sshd命令),并将以下行添加到file:

auth需要pam_google_authenticator。so

下一步,打开/ etc / ssh / sshd_config文件,找到ChallengeResponseAuthentication行,并将其更改为如下所示:

ChallengeResponseAuthentication yes

(如果ChallengeResponseAuthentication行不存在,请将上述行添加到该文件。)

最后,重新启动SSH服务器,所以您的更改将生效109mh1112

sudo服务ssh restart

未分类

当您尝试通过SSH登录时,系统将提示您输入密码和Google Authenticator代码。

未分类

利用SSH上传、下载(使用sz与rz命令)

简述

通常,利用SSH管理远程Linux服务器时,经常需要与本地交互文件。当然,我们可以利用FTP方式,比如通过Filezilla客户端软件。不过直接使用SSH软件(SecureCRT、Xshell)自带的上传和下载功能无疑使最方便快捷的。通常SSH软件支持的文件传输协议主要有ASCII、Xmodem、Zmodem等。

rz,sz是便是linux/Unix同Windows进行ZModem文件传输的命令行工具。

1、使用前提

  • 首先,你的Linux端(CentOS, Ubuntu)需要安装rz/sz命令,也就是 lszrz 包。
  • 其次,windows端需要支持ZModem的telnet/ssh客户端(Xshell,SecureCRT支持,好像putty不支持),SecureCRT就可以用SecureCRT登陆到Unix/Linux主机(telnet或ssh均可)
  • 运行命令rz,即是接收文件,xshell就会弹出文件选择对话框,选好文件之后关闭对话框,文件就会上传到linux里的当前目录。如果要上传文件,直接用鼠标点住文件往X-shell里面一拖即是
  • 运行命令 sz file 就是发文件到windows上(保存的目录是可以配置) 比ftp命令方便多了,而且服务器不用再开FTP服务了

2、文件传输协议

文件传输是数据交换的主要形式。在进行文件传输时,为使文件能被正确识别和传送,我们需要在两台计算机之间建立统一的传输协议。这个协议包括了文件的识别、传送的起止时间、错误的判断与纠正等内容。常见的传输协议有以下几种:

  • ASCII:这是最快的传输协议,但只能传送文本文件。
  • Xmodem:这种古老的传输协议速度较慢,但由于使用了CRC错误侦测方法,传输的准确率可高达99.6%。
  • Ymodem:这是Xmodem的改良版,使用了1024位区段传送,速度比Xmodem要快
  • Zmodem:Zmodem采用了串流式(streaming)传输方式,传输速度较快,而且还具有自动改变区段大小和断点续传、快速错误侦测等功能。这是目前最流行的文件传输协议。

3、在Linux上安装lrzsz

单单是SSH客户端软件支持以上文件传输协议(ASCII,Xmodem,Ymodem,Zmodem)还不行,我们的Linux服务器上也得安装相应的软件,以支持这些文件传输协议才行。在Linux上,lrzsz就是完成此任务的,lrzsz就是一个支持Zmodem 传输协议的工具。我们通过sz/rz两个命令,分别发送/接收文件。如果我们的系统中没有安装lrzsz这个包,就会报错,安装即可解决。

[root@localhost ~]# rz
-bash: rz: command not found
## For CentOS/RHEL
[root@localhost ~]# yum -y install lrzsz
## For Ubuntu
# sudo apt-get install lrzsz

4、理解记忆

其中,对于sz和rz的理解与记忆我用了如下的方法(很多时候容易搞混):

  • sz中的s意为send(发送),告诉客户端,我(服务器)要发送文件 send to cilent,就等同于客户端在下载。
  • rz中的r意为received(接收),告诉客户端,我(服务器)要接收文件 received by cilent,就等同于客户端在上传。

记住一点,不论是send还是received,动作都是在服务器上发起的。我们习惯了说上传或是下载,其实大可不必。使用这两个命令,只要思考一点,是要把文件从服务器上发送出去,还是从客户端接收回来,就可以了。

好吧,最后总结为一句话:

我(客户端)上传,你(服务器)接收(RZ),我下载(客户端),你(服务器)发送(SZ)。

5、简单用法

  • sz用法:发送出去
### 下载一个文件: 
# sz filename 
### 下载多个文件: 
# sz filename1 filename2
### 下载dir目录下的所有文件,不包含dir下的文件夹: 
# sz dir/*
  • rz用法:接收回来
### 直接键入rz命令即可
# rz
### 直接拖动文件到 xshell, 或者 SecureCRT 窗口即可
输入rz回车后,会出现文件选择对话框,选择需要上传文件,一次可以指定多个文件,上传到服务器的路径为当前执行rz命令的目录。

6、设置默认路径

SecureCRT:

设置上传和下载的默认目录:

  • 英文版: options — session options — X/Y/Zmodem。

  • 中文版: 选项— 会话选项— X/Y/Zmodem。

未分类

未分类

Xshell:

设置上传和下载的默认目录:

File -> Properties -> ZMODEM

未分类

未分类

7、操作演示

(仅演示Xshell,其他类似)

rz命令(下载)

当我们键入rz命令之后,会弹出文件选择对话框,选择需要传输的文件,点击 Add 即可。

接收的目录就是我们当前执行rz命令的目录。

未分类

今天又发现一个更简单直接的方法,直接选中文件,用鼠标点住文件往Xshell里面一拖就可以了。

sz命令(上传)

假设我要发送文件,直接使用sz命令, 其后接上文件名即可。同理,敲下回车后,也会弹出对话框,让我们选择接收的文件夹。

[root@localhost ~]# sz nagios-4.0.7.tar.gz  nagios-plugins-2.0.3.tar.gz

8、问题

xshell或者SecureCRT 启动 tmux或screen之后,sz, rz 命令都无法弹出正常的文件选择窗口,该如何解决?

看起来 tmux 下不支持 zmodem,所以这两个命令也用不了。

配置putty或SecureCRT防止SSH连接中断

当用SSH协议连接Linux服务器时,有时几分钟内没有操作,连接就会中断,必须重新登陆。

本文提供解决方案供参考:

8以CentOS 6.4为例:

1、修改ssh配置文件

vi /etc/ssh/sshd_config

找到ClientAliveInterval,指定了服务器端向客户端发送请求消息的时间间隔, 默认是0,不发送。

将后面的数值设置修改,单位为秒,如10分钟,则可设置参数为600
再找到ClientAliveCountMax,指如果发现客户端没有响应,则判断为一次超时,这个参数设置允许超时的次数,比如10,则代表允许超时 6000秒 = 100分钟。

2、修改SecureCRT会话属性配置

未分类

3、Putty

启用putty keepalive

putty -> Connection -> Seconds between keepalives ( 0 to turn off ),默认为0,改为60。

如下图所示

未分类

其他工具也可根据实际情况修改保活机制相关配置。

利用ssh隧道解决登录vps服务器慢的问题

1. 背景

linode的vps在某些网络下访问比较慢,甚至还有丢包的情况。但是从国内的服务器ping过去,一切正常。之前听说过ssh端口转发及隧道特性,于是考虑在通过正常的国内服务器去登录vps。

2. 传统做法

先登录稳定服务器,然后在上面再通过ssh登录到目标机器。虽然简单直接,但这样的缺点也显而易见,证书管理不方便。

3. SSH隧道方式

这里是基于稳定服务器将vps的端口转发到了本地。

  • step1 先登录稳定服务器
    ssh -L 36000:VPS-IP:22 稳定服务器IP
    这里通过稳定服务器,将VPS的22端口转发到了本地的36000端口

  • step2 登录本地端口
    ssh -p 36000 localhost
    由于是转发,这里之前在VPS上配置的证书依然可以使用,只是换了一个端口和IP而已。

4. 其他使用场景

本地端口转发还有一个比较实用的场景,就是可以将服务器的内网端口转发到本地。比如,有些开发同学习惯通过本地的IDE连接远程的mysql,这样将数据库的远程访问权限打开有一定安全隐患。体验下另外一种方式:

# 先将远程服务器的192.168.2.110:3307端口映射到本地33070
ssh -L 33070:192.168.2.110:3307 跳板机IP
#登录本地33070端口,注意将host指定为127.0.0.1
mysql -P 33070 -h127.0.0.1 -uusername -p'password'

5. 其他转发方式

除了将远程端口转发到本地(Local Forwarding),还有两种方式:

  • 动态端口转发(Dynamic Forwarding)
    ssh -D [bind_addr]:port user@server
    适合代理方式

  • 远程端口转发(Remote Forwarding)
    ssh -R [bind_addr]:port:host:hostport user@server
    相当于将host:hostport映射到了server:port上

解决debian9系统安装后root用户无法通过ssh连接的问题

小L有一个hostigation 256d KVM小鸡在吃灰,今天没事拿出来折腾,看到后台居然有windows2008的系统可以安装,就手贱点了reinstall,安装不成功,显示初始化什么失败之类的。然后再后台面板看到最新出来的debian9的ROM,就挂载了重新安装,经过一番折腾终于安装成功,但是悲催的发现在本地的ssh下居然root用户无法登录,另外一个受限账户可以登录,未远程通过VNC却都可以登录。然后百度了一圈,网络上的解决方案都是针对debian8及以下的系统解决方案,按照这个方案修改做如下修改:

vi /etc.ssh/sshd_config

把文本中的

#PermitRootLogin no

前的“#”去掉”no”改成“yes”

然而,debian9的配置文件中并没有这段代码!仔细查看后把

#PermitRootLogin prohibit-password

改成

PermitRootLogin yes

并reboot后解决。