sshd服务分析

00、阐述 sshd 服务

  基本上,所有的 ssh 相关设定都放在 /etc/ssh/sshd_config 里面!不过,每个 Linux distribution 的预设设定都不太相同, 所以我们有必要来了解一下整个设定值的意义为何才好!(一般就看启动脚本的定义路径,像基于源码升级openssh

service sshd restart |stop |reload   #sshd脚本路径/etc/init.d/sshd

 

[root@mvp ~]# cat /etc/init.d/sshd 
#!/bin/bash
#
# sshd        Start up the OpenSSH server daemon
#
# chkconfig: 2345 55 25
# description: SSH is a protocol for secure remote shell access. \
#              This service starts up the OpenSSH server daemon.
#
# processname: sshd    #sshd进程的默认配置
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid

### BEGIN INIT INFO
# Provides: sshd
# Required-Start: $local_fs $network $syslog
# Required-Stop: $local_fs $syslog
# Should-Start: $syslog
# Should-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start up the OpenSSH server daemon
# Description:       SSH is a protocol for secure remote shell access.
#             This service starts up the OpenSSH server daemon.
### END INIT INFO

# source function library
. /etc/rc.d/init.d/functions

# pull in sysconfig settings
[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd

RETVAL=0
prog="sshd"
lockfile=/var/lock/subsys/$prog

# Some functions to make the below more readable  #文件的路径
KEYGEN=/usr/bin/ssh-keygen
SSHD=/usr/sbin/sshd
RSA1_KEY=/etc/ssh/ssh_host_key
RSA_KEY=/etc/ssh/ssh_host_rsa_key
DSA_KEY=/etc/ssh/ssh_host_dsa_key
PID_FILE=/var/run/sshd.pid

runlevel=$(set -- $(runlevel); eval "echo \$$#" )

fips_enabled() {
    if [ -r /proc/sys/crypto/fips_enabled ]; then
        cat /proc/sys/crypto/fips_enabled
    else
        echo 0
    fi
}

do_rsa1_keygen() {
    if [ ! -s $RSA1_KEY -a `fips_enabled` -eq 0 ]; then
        echo -n $"Generating SSH1 RSA host key: "
        rm -f $RSA1_KEY
        if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/
null; then            chmod 600 $RSA1_KEY
            chmod 644 $RSA1_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $RSA1_KEY.pub
            fi
            success $"RSA1 key generation"
            echo
        else
            failure $"RSA1 key generation"
            echo
            exit 1
        fi
    fi
}

do_rsa_keygen() {
    if [ ! -s $RSA_KEY ]; then
        echo -n $"Generating SSH2 RSA host key: "
        rm -f $RSA_KEY
        if test ! -f $RSA_KEY && $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/nul
l; then            chmod 600 $RSA_KEY
            chmod 644 $RSA_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $RSA_KEY.pub
            fi
            success $"RSA key generation"
            echo
        else
            failure $"RSA key generation"
            echo
            exit 1
        fi
    fi
}

do_dsa_keygen() {
    if [ ! -s $DSA_KEY ]; then
        echo -n $"Generating SSH2 DSA host key: "
        rm -f $DSA_KEY
        if test ! -f $DSA_KEY && $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/nul
l; then            chmod 600 $DSA_KEY
            chmod 644 $DSA_KEY.pub
            if [ -x /sbin/restorecon ]; then
                /sbin/restorecon $DSA_KEY.pub
            fi
            success $"DSA key generation"
            echo
        else
            failure $"DSA key generation"
            echo
            exit 1
        fi
    fi
}

do_restart_sanity_check()
{
    $SSHD -t
    RETVAL=$?
    if [ $RETVAL -ne  0 ]; then
        failure $"Configuration file or keys are invalid"
        echo
    fi
}

start()
{
    [ -x $SSHD ] || exit 5
    [ -f /etc/ssh/sshd_config ] || exit 6
    # Create keys if necessary
    if [ "x${AUTOCREATE_SERVER_KEYS}" != xNO ]; then
        do_rsa1_keygen
        do_rsa_keygen
        do_dsa_keygen
    fi

    echo -n $"Starting $prog: "
    $SSHD $OPTIONS && success || failure
    RETVAL=$?
    [ $RETVAL -eq 0 ] && touch $lockfile
    echo
    return $RETVAL
}

stop()
{
    echo -n $"Stopping $prog: "
    killproc -p $PID_FILE $SSHD
    RETVAL=$?
    # if we are in halt or reboot runlevel kill all running sessions
    # so the TCP connections are closed cleanly
    if [ "x$runlevel" = x0 -o "x$runlevel" = x6 ] ; then
        trap '' TERM
        killall $prog 2>/dev/null
        trap TERM
    fi
    [ $RETVAL -eq 0 ] && rm -f $lockfile
    echo
}

reload()
{
    echo -n $"Reloading $prog: "
    killproc -p $PID_FILE $SSHD -HUP
    RETVAL=$?
    echo
}

restart() {
    stop
    start
}

force_reload() {
    restart
}

rh_status() {
    status -p $PID_FILE openssh-daemon
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        start
        ;;
    stop)
        if ! rh_status_q; then
            rm -f $lockfile
            exit 0
        fi
        stop
        ;;
    restart)
        restart
        ;;
    reload)
        rh_status_q || exit 7
        reload
        ;;
    force-reload)
        force_reload
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        if [ -f $lockfile ] ; then
            do_restart_sanity_check
            if [ $RETVAL -eq 0 ] ; then
                stop
                # avoid race
                sleep 3
                start
            else
                RETVAL=6
            fi
        fi
        ;;
    status)
        rh_status
        RETVAL=$?
        if [ $RETVAL -eq 3 -a -f $lockfile ] ; then
            RETVAL=2
        fi
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-rest
art|status}"        RETVAL=2
esac
exit $RETVAL

 

01、sshd_config参数含义

[root@linux ~]# vi /etc/ssh/sshd_config
# 1. 关于 SSH Server 的整体设定,包含使用的 port ,以及使用的密码演算方式
# 先留意一下,在预设的档案内,只要是被注解的设定值(#),即为『预设值!』  #默认注释后面的值就是配置默认值
Port 22
# SSH 预设使用 22 这个port,也可以使用多个port,即重复使用 port 这个设定项目!
# 例如想要开放 sshd 在 22 与 443 ,则多加一行内容为∶
Port 443 

Protocol 1,2
# 选择的 SSH 协定版本,可以是 1 也可以是 2 ,
# 如果要同时支持两者,就必须要使用 2,1 这个分隔了(Protocol 1,2)!
# 目前我们会建议您,直接使用 Protocol 2 即可!

#Protocol 2

#ListenAddress 0.0.0.0

ListenAddress 192.168.0.100   #对于多网卡,制定监听IP,默认监听所有

#PidFile /var/run/sshd.pid
# 可以放置 SSHD 这个 PID 的档案!左列为预设值

#LoginGraceTime 2m
# 当使用者连上 SSH server 之后,会出现输入密码的画面,在该画面中,
# 在多久时间内没有成功连上 SSH server ,就断线!若无单位则预设时间为秒!

#Compression yes
# 是否可以使用压缩指令?当然可以

# 2. 说明主机的 Private Key 放置的档案,预设使用下面的档案即可!
#HostKey /etc/ssh/ssh_host_key # SSH version 1 使用的私钥
#HostKey /etc/ssh/ssh_host_rsa_key # SSH version 2 使用的 RSA 私钥
#HostKey /etc/ssh/ssh_host_dsa_key # SSH version 2 使用的 DSA 私钥

 

#KeyRegenerationInterval 1h
# 由前面连线的说明可以知道, version 1 会使用 server 的 Public Key ,
# 那么如果这个 Public Key 被偷的话,岂不完蛋?所以需要每隔一段时间
# 来重新建立一次!这里的时间为秒!不过我们通常都仅使用 version 2 ,
# 所以这个设定可以被忽略喔!

#ServerKeyBits 768
# 没错!这个就是 Server key 的长度!用预设值即可。# 3. 关于登录档的讯息资料放置与 daemon 的名称!

SyslogFacility AUTHPRIV
# 当有人使用 SSH 登入系统的时候,SSH会记录资讯,这个资讯要记录在什么 daemon name
即是 /var/log/secure 里面!什么?忘记了!

#LogLevel INFO
# 登录记录的等级!嘿嘿!任何讯息!同样的,忘记了就回去参考!

# 4. 安全设定项目!极重要!
PermitRootLogin no  # yes  允许root远程登录
# 是否允许 root 登入!预设是允许的,但是建议设定成 no!

#UserLogin no
# 在 SSH 底下本来就不接受 login 这个程序的登入!

#StrictModes yes
# 当使用者的 host key 改变之后,Server 就不接受连线,可以抵挡部分的木马程序!

#RSAAuthentication yes # 是否使用纯的 RSA 认证!?仅针对 version 1 !
#PubkeyAuthentication yes # 是否允许 Public Key ?当然允许!仅针对 version 2

#AuthorizedKeysFile .ssh/authorized_keys   #默认公钥存储位置
# 上面这个在设定若要使用不需要密码登入的帐号时,那么那个帐号的存放档案所在档名!
# 这个设定值很重要喔!档名给他记一下!

# 4.2 认证部分
#RhostsAuthentication no
# 本机系统不使用 .rhosts,因为仅使用 .rhosts太不安全了,所以这里一定要设定为 no

#IgnoreRhosts yes
# 是否取消使用 ~/.ssh/.rhosts 来做为认证!当然是!

#RhostsRSAAuthentication no #
# 这个选项是专门给 version 1 用的,使用 rhosts 档案在 /etc/hosts.equiv
# 配合 RSA 演算方式来进行认证!不要使用啊!

#HostbasedAuthentication no
# 这个项目与上面的项目类似,不过是给 version 2 使用的!

#IgnoreUserKnownHosts no
# 是否忽略家目录内的 ~/.ssh/known_hosts 这个档案所记录的主机内容?
# 当然不要忽略,所以这里就是 no !

PasswordAuthentication yes
# 密码验证当然是需要的!所以这里写 yes !

#PermitEmptyPasswords no
# 若上面那一项如果设定为 yes 的话,这一项就最好设定为 no ,
# 这个项目在是否允许以空的密码登入!当然不许!

ChallengeResponseAuthentication no
# 允许任何的密码认证!所以,任何 login.conf 规定的认证方式,均可适用!
# 但目前我们比较喜欢使用 PAM 模组帮忙管理认证,因此这个选项可以设定为 no 喔!
UsePAM yes
# 利用 PAM 管理使用者认证有很多好处,可以记录与管理。
# 所以这里我们建议您使用 UsePAM 且 ChallengeResponseAuthentication 设定为 no

# 4.3 与 Kerberos 有关的参数设定!因为我们没有 Kerberos 主机,所以底下不用设定!
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosTgtPassing no

# 4.4 底下是有关在 X-Window 底下使用的相关设定!
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes

# 4.5 登入后的项目∶
PrintMotd yes   #
# 登入后是否显示出一些资讯呢?例如上次登入的时间、地点等等,预设是 yes
# 亦即是列印出 /etc/motd  #登录进去提示的信息

PrintLastLog yes
# 显示上次登入的资讯!可以啊!预设也是 yes !

KeepAlive yes
# 一般而言,如果设定这项目的话,那么 SSH Server 会传送KeepAlive 的讯息给
# Client端,以确保两者的连线正常!在这个情况下,任何一端死掉后,SSH可以立刻知道!
# 而不会有僵尸程序的发生!

UsePrivilegeSeparation yes
# 使用者的权限设定项目!就设定为 yes 吧!

MaxStartups 10
# 同时允许几个尚未登入的连线画面?当我们连上 SSH ,但是尚未输入密码时,
# 这个时候就是我们所谓的连线画面!在这个连线画面中,为了保护主机,
# 所以需要设定最大值,预设最多十个连线画面,而已经建立连线的不计算在这十个当中

# 4.6 关于使用者抵挡的设定项目∶
DenyUsers *
# 设定受抵挡的使用者名称,如果是全部的使用者,那就是全部挡吧!
# 若是部分使用者,可以将该帐号填入!例如下列!
DenyUsers test  #禁止登录用户、用户组

DenyGroups test
# 与 DenyUsers 相同!仅抵挡几个群组而已!

# 5. 关于 SFTP 服务的设定项目!
Subsystem sftp /usr/lib/ssh/sftp-server   #sftp登录默认都是开启

02、key生成

[test2@test2 ~]$ ssh-keygen -t rsa <==这个步骤在产生 Key pair  # -t   dsa  默认rsa加密
Generating public/private rsa key pair.
Enter file in which to save the key (/home/test2/.ssh/id_rsa): <==这里按下Enter
Enter passphrase (empty for no passphrase): <==这里按 Enter    #秘钥加密的密码
Enter same passphrase again: <==再按一次 Enter
Your identification has been saved in /home/test2/.ssh/id_rsa. <==这是私钥
Your public key has been saved in /home/test2/.ssh/id_rsa.pub. <==这是公钥
The key fingerprint is:
c4:ae:d9:02:d1:ba:06:5d:07:e6:92:e6:6a:c8:14:ba test2@test2.linux.org
# 注意∶ -t 指的是『使用何种密码演算方式?』由于我们使用 RSA ,
# 所以直接输入 -t rsa 即可建立两支 Keys !
# 此外,建立的两把 Keys 都放置在家目录下的 .ssh 这个目录中!
# 察看一下这两把 Keys 吧!

[test2@test2 ~]$ ll ~/.ssh
total 12
-rw------- 1 test2 test2 887 Nov 12 22:36 id_rsa
-rw-r--r-- 1 test2 test2 233 Nov 12 22:36 id_rsa.pub
-rw-r--r-- 1 test2 test2 222 Oct 31 11:20 known_hosts


1. 先在 Client 端以 sftp 将公钥丢到 test 上面去!
[test2@test2 ~]$ cd ~/.ssh
[test2@test2 .ssh]$ scp id_rsa.pub test@192.168.0.2:~/
test@192.168.0.2's password:
id_rsa.pub 100% 233 0.2KB/s 00:00

2. 到 Server 上面,将公钥转存到 authorized_keys 档案中!
[test@linux ~]$ cd ~/.ssh
[test@linux .ssh]$ cat ../id_rsa.pub >> authorized_keys
请注意上面的机器!由于 authorized_keys 可以保存相当多的公钥内容,因此, 可以使用 >> 的方式来将 Client 端的公钥新增到该档案内!!做完这一步一后,未来 test2 就可以直接在 test2sweet.com以

注意:假定远程主机没有authorized_keys,亦可以使用   ssh-copy-id -i ~/.ssh/xx.pub     user@ip   自动生成authorized_keys


[test2@test2 ~]$ ssh test@linuxsweet.com
• Client 必须制作出 Public & Private 这两把 keys,且 Private 需放到 ~/.ssh/ 内;
• Server 必须要有 Public Key ,且放置到使用者家目录下的 ~/.ssh/authorized_keys;
未来,当您还想要登入其他的主机时,只要将您的 public key (就是 id_rsa.pub 这个档案) 给他 copy 到其他主机上面去,并且新增到某帐号的 ~/.ssh/authorized_keys 这个档案中!哈哈!成功

安全设定∶
老实说,大家都被『SSH 是个安全的服务』所欺骗了!其实 sshd 并不怎么安全的!翻开 openssh 的过去历史来看,确实有很多人是利用 ssh 的程序漏洞来取得远端主机 root 的权限,进一步黑掉对方的主机!  #openssh的漏洞是致命的,多关注最新的安全动态

分别可以由∶ 

• /etc/ssh/sshd_config
/etc/hosts.allow, /etc/hosts.deny  
• iptables

• /etc/ssh/sshd_config
一般而言,这个档案的预设项目就已经很完备了!所以,事实上是不太需要更动他的! 但是,如果您有些使用者方面的顾虑,那么可以这样修正一些问题呢!
o 禁止 root 的登入∶
任何时候,不许 root 以远端连线的方式登入,都会是一个好主意!所以这里蛮建议大家直接将 root 的登入权限拿掉吧!所以,可以修改 /etc/ssh/sshd_config 这个档案的内容为∶
[root@linux ~]# vi /etc/ssh/sshd_config
PermitRootLogin no <== 将他改成 no 吧!
[root@linux ~]# /etc/init.d/sshd restart

o 不许某个群组登入∶
有些特殊情况中,我们想要让使用者只能使用 sendmail, pop3, ftp 等,但是不希望他可以远端连线进来,那么您可以这样做∶

1. 将这些使用者都归纳在某一个特殊群组之下,例如 nossh 这个群组好了;
2. 在 /etc/ssh/sshd_config 当中加入这一行∶『 DenyGroups nossh 』
3. 重新启动 sshd ∶ /etc/init.d/sshd restart

这样就OK!

o 不许某个使用者登入∶
跟 DenyGroups 类似,使用 DenyUsers 即可!参考 sshd_config 的设定喔!


• /etc/hosts.allow 及 /etc/hosts.deny
简单的方法就是∶
[root@linux ~]# vi /etc/hosts.allow
sshd: 192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4, 192.168.0.5: allow  
[root@linux ~]# vi /etc/hosts.deny
sshd : ALL : spawn (/bin/echo Security notice from host `/bin/hostname`; \
/bin/echo; /usr/sbin/safe_finger @%h ) | \
/bin/mail -s "%d -%h security" root@localhost & \
: twist ( /bin/echo -e "\n\nWARNING connectin not allowed.". )

posted @ 2017-09-02 15:03  mvpbang  阅读(993)  评论(1编辑  收藏  举报