SSH 限制
SSH 限制
限制 SSH 连接
通过使用用户、组和拒绝/允许条目限制 SSH 用户连接您的主机。还可以针对各个主机使用 TCP Wrappers。
评论
David Tansley, 系统管理员, Ace Europe
年 月 日
expand
内容 在 IBM Bluemix 云平台上开发并部署您的下一个应用。
开始您的试用
简介
SSH (OpenSSH) 提供到远程主机的安全加密连接。如果用户有有效的 AIX® 帐户,就可以通过 SSH 连接。但是,对于任何关注安全性的系统来说,很可能需要限制某些用户或主机通过 SSH 连接指定的系统。SSH 提供两种限制用户访问的机制:Deny 和 Allow 属性。这些关键词基于用户和组列表。还可以使用 TCP Wrappers 阻止来自已知或未知主机的 SSH 连接。我建议使用 TCP Wrappers 按主机名/域或 IP 阻止主机,并且使用 sshd_config 实现基于用户/组的访问控制。
根据安装的 SSH 变体不同,可以在两个地方找到配置文件和 SSH 守护进程。对于 AIX OpenSSH,配置文件在 /etc/ssh 中,SSH (sshd) 守护进程在 /usr/sbin/sshd 文件中。
对于其他 OpenSSH 类型,配置文件通常在 /usr/local/etc 中,SSH (sshd) 守护进程在 /usr/local/sbin/sshd 中。
回页首
用 TCP Wrappers 限制 SSH
TCP Wrappers 用于阻止或允许从 inetd 启动的基于 TCP 的应用程序,比如 telnet 或 FTP 服务。根据规则,SSH 不从 inetd 启动。如果希望通过 TCP Wrappers 控制 SSH 访问,就需要把 libwrap.a 复制到 LIBPATH 指向的目录中(对于第三方应用程序,这个目录是 /usr/local/lib)。TCP Wrappers 守护进程是 tcpd。
查看 /var/adm/messages 文件,可能会找到 SSH 连接尝试。这些可能是来自您的网络中本地机器的完全无恶意的连接尝试,也可能是来自未知主机的强力连接尝试。应该进一步研究这些条目。如果发现有非法访问尝试,就应该阻止它们。尽管可以使用 sshd_config 文件阻止主机,但是我建议使用 TCP Wrappers 阻止主机,因为这是阻止到达的 TCP 连接的主要机制。
TCP Wrappers (tcpd) 通过读取两个文件决定应该允许还是拒绝到达的 TCP 连接。这两个文件是:
/etc/hosts.allow
/etc/hosts.deny
对这两个文件的修改是动态的。这两个文件中的模式匹配规则控制拒绝或允许什么。这些规则既可以很复杂,也可以很简单。首先搜索 hosts.allow。如果找到匹配的模式,就允许连接,或者更准确地说,tcpd 死亡,让真正提供服务的守护进程接管。然后在 hosts.deny 中搜索匹配的模式。如果找到匹配,tcpd 就拒绝此连接访问系统。简单地说,这意味着先应用 hosts.allow 规则,然后应用 hosts.deny 规则。一般的做法是先允许您信任的主机,然后拒绝所有其他主机。
现在,我们通过一些示例了解 TCP Wrappers 如何控制对主机的 SSH 访问。假设我们属于 drwho.com 域,希望只允许属于这个域的用户通过 SSH 连接。可以使用以下规则来实现:
# cat hosts.allow
sshd : .drwho.com # cat hosts.deny
ALL : ALL
为了进一步细化前面的示例,我们仍然允许来自 drwho.com 域的所有连接,同时也允许以下 IP 地址范围 172.24.., 172.24..(IP 地址末尾的点号表示要匹配点号后面的任何内容)。注意,在下面的示例中,每个模式由逗号分隔。
# cat hosts.allow
sshd: .drwho.com , 172.24.. , 172.24..
有时候,希望允许域中的所有主机,但是某些主机除外。例如,一个系统是生产系统,不希望允许从开发系统连接它。下面的规则允许前面示例中允许的所有主机,但是以下主机除外:dev01 和 dev02。
# cat hosts.allow
sshd: .drwho.com , 172.24.. , 172.24.. , EXCEPT dev01, dev02
还可以在 hosts.allow 或 hosts.deny 文件中使用 username@hostname 格式。例如:
dxtans@dev01
可能必须提供 FQDN(完全限定的域名)。为了查明这一点,在消息文件中查看 TCP Wrappers 如何解析主机名,然后相应地修改 hosts.allow 文件。
对于 username@host 格式,我喜欢用 sshd_config 文件控制访问。这是因为这样就可以使用 TCP Wrappers 只为 telnet、FTP 等基于 TCP 的服务进行主机身份验证,只用 ssh_config 文件为 SSH 进行用户/组身份验证。从系统管理员的角度来看,这样更容易管理主机和用户访问控制。
要想通过 syslog 把连接记录在 /var/adm/messages 中,在 /etc/syslogd.conf 中必须有以下条目之一:
*.info /var/adm/messages
或
*.auth /var/adm/messages
必须重新启动 syslogd,修改才能生效:
# refresh -s syslogd
在消息文件中,成功连接的典型条目(在这里,用户 dxtans 来自属于 drwho.com 域的主机 tardis)如下:
May :: rs6000 auth|security:info sshd[]: Accepted password for dx
tans from tardis port ssh2
由于应用了 hosts.allow 文件中的规则,来自主机 dev01 的用户的连接尝试被拒绝,其消息如下:
May :: rs6000 auth|security:info sshd[]: refused connect from dev01
回页首
用 sshd_config 限制连接
在 sshd_config 中,有四个条目:
AllowUsers
AllowGroups
DenyUsers
DenyGroups
如果没有这些关键词,只需根据需要创建它们。必须只创建您需要的关键词,以免出现不可靠的结果。AllowUsers 和 DenyUsers 列表是由空格分隔的有效用户名,AllowGroups 和 DenyGroups 只能是现有的有效组。按以下次序匹配模式:DenyUsers,AllowUsers,DenyGroups,AllowGroups。
对 sshd_config 文件的任何修改要到重新启动 sshd 之后才会生效,如下所示:
# stopsrc -s sshd
# startsrc -s sshd
如果在 AllowUsers 列表中设置用户 ID,那么只有这些用户可以通过 SSH 连接。对于 DenyUsers 列表也是如此,只拒绝 DenyUsers 列表中包含的用户访问。同样的规则也适用于组列表。如果同时使用允许列表和拒绝列表,就非常让人迷惑,所以不要这样做。应该根据自己的安全需求,只使用允许列表或拒绝列表之一。
如果用户在系统上有帐户,但是在 AllowUsers 列表中没有他们的用户 ID,就拒绝他们访问。同样的规则也适用于 DenyUsers 列表。现在来看一个示例,假设 AllowUsers 列表包含以下内容:
AllowUsers bravo charlie mother oscar delta echoa hotel juliet papa ukflag
如果用户 alpha 尝试通过 SSH 访问,那么该访问会遭到拒绝,因为这个用户名没有出现在 AllowUsers 列表中。
login as: alpha
alpha@rs6000's password:
Access denied
alpha@rs6000's password:
Access denied
alpha@rs6000's password:
通过查看 /var/adm/messages 文件确认这一点,这里的消息表明在 AllowUsers 列表中没有列出用户 alpha。
Jun :: rs6000 auth|security:info sshd[]: User alpha from tardis
not allowed because not listed in AllowUsers
Jun :: rs6000 auth|security:info sshd[]: Failed none for invalid
user alpha from tardis port ssh2
现在看看 DenyUsers 列表,假设这个列表包含以下内容:
DenyUsers bravo charlie mother oscar delta echoa hotel juliet papa ukflag
现在,只要用户在系统上有帐户,而且其用户名没有在 DenyUsers 列表中列出,就允许他们通过 SSH 访问。
如果用户 alpha 尝试通过 SSH 访问,那么允许此用户访问,因为他的用户名没有包含在 DenyUsers 列表中。可以通过查看消息文件确认这一点:
Jun :: rs6000 auth|security:info sshd[]: Accepted password for
alpha from tardis port ssh2
但是,如果 DenyUsers 列表中包含的用户 bravo 尝试通过 SSH 访问,其访问会遭到拒绝:
login as: bravo
bravo@rs6000's password:
Access denied
bravo@rs6000's password:
同样,可以通过查看消息文件检查拒绝的原因:
Jun :: rs6000 auth|security:info sshd[]: User bravo from tardis
not allowed because listed in DenyUsers
Jun :: rs6000 auth|security:info sshd[]: Failed none for invalid
user bravo from tardis port ssh2
要保持简单。使用 AllowUsers 列表只允许您希望的用户访问。拒绝其他所有用户;不需要添加 DenyUsers 列表。
为了避免模式匹配产生出乎意料的结果,我强烈建议不要同时使用组列表和用户列表,而是只使用用户列表(允许或拒绝)或组列表(允许或拒绝)之一。
现在看看不适当的设置会造成怎样的混乱,假设设置了以下条目:
AllowUsers alpha
DenyUsers bravo charlie mother oscar delta echoa hotel juliet papa ukflag
考虑到模式匹配次序,我们现在可以声明,对 DenyUsers 列表中包含的用户都不授予任何访问权,只允许用户 alpha 访问。对于这种情况,我建议只使用 AllowUsers 列表。如果用户 ID 没有在允许列表中列出,就不能连接,无论拒绝列表包含哪些用户。
同样的原则也适用于组。假设设置了以下条目:
AllowGroups water
DenyGroups nossh
water 组的成员是:
# lsgroup -a users water
water users=delta,echoa,golf,plutt
现在,如果用户 dxtans(staff 和 admin 组的成员)
# id dxtans
uid=(dxtans) gid=(staff) groups=(admin)
尝试连接,那么访问会失败,在 /var/adm/messages 中会记录以下条目:
Jun :: rs6000 auth|security:info sshd[]: User dxtans from tardis
not allowed because none of user's groups are listed in AllowGroups
这是因为 dxtans 不在允许列表中,也不在拒绝列表中。
创建一个不允许通过 SSH 访问的用户组可能有好处,因为这会减少维护工作量,然后创建一个允许通过 SSH 访问的用户组。例如,假设有一个称为 nossh 的组,其中包含不允许通过 SSH 访问的用户:
# lsgroup -a users nossh
nossh users=golf,hotel,india,julie
在 sshd_config 文件中,有以下条目:
DenyGroups nossh
现在,属于 nossh 组的所有用户都被拒绝访问。例如,当属于 nossh 组的用户 golf 尝试通过 SSH 访问时,在消息文件中可以看到以下消息:
Jun :: rs6000 auth|security:info sshd[]: User golf from tardis
not allowed because a group is listed in DenyGroups
如果系统上的用户很多,使用组列表可能比用户列表更合适。
回页首
控制 root 访问
在处理来自远程主机的直接 root SSH 访问时,我建议最好限制能够作为 root 用户通过 SSH 连接的主机。这种方式让管理员可以控制 root 用户能够从哪里通过 SSH 连接,由此控制远程 root 连接。
为了通过 sshd_conf 文件控制用户和主机的访问,可以使用以下格式:root@<hostname> 或 root@<hostname.domain>。
需要查看 SSH 在 /var/adm/messages 文件中采用什么格式,主机是解析为短主机名还是长主机名。查明这一点之后,只需在 AllowUsers 列表中加入相应的条目。如果不确定是短主机名还是长主机名(因为这取决于发起 SSH 连接的操作系统),那么最好同时包含这两种形式。
例如,要想只允许来自主机 tardis(属于 drwho 域)的 root 访问,可以使用以下设置:
AllowUsers root@tardis root@tardis.drwho.com
当然,在真实环境中,上面的列表还包含其他用户。
如果您有一台部署服务器,且只有该部署服务器上的 root 用户(在上面的示例中)可以从一个指定主机通过 SSH 和 SCP 访问所有客户机,那么非常适合采用以上方法。
回页首
自动生成用户列表
自动生成用户列表作为允许或拒绝列表是有好处的。随着时间的推移,经常会添加和删除用户,所以很容易忘记更新列表。应该生成什么列表呢?我建议只生成允许列表。判断用户是否不在 AllowUsers 列表中更方便。如果用户不在此列表中,就拒绝访问。按照什么规则允许用户进入 AllowUsers 列表呢?先考虑用户的属性是否表明他可以执行远程 rlogin/telnet (rlogin=true),然后考虑为什么不允许他通过 SSH 访问。采用这个规则就会立即排除所有系统和应用程序所有者帐户,只留下普通用户。
在典型的系统上,所有系统帐户和应用程序所有者应该是不可登录的。因此,只能通过 su 或 sudo 访问这些帐户。
只在处理特殊事件时手动编辑列表,比如在应用程序交付期间进一步允许(或拒绝)临时访问。清单 演示一种实现方法。首先确定 sshd_config 文件的位置,这样就知道要更新的 SSH 版本。接下来,收集主机上 rlogin 属性为 true 的所有用户,但是不包括 root 用户。然后,读取 /tmp/ssh_ignore 文件,从生成的用户列表中删除匹配的所有用户。使用 ssh_ignore 文件让管理员能够方便地控制哪些用户不应该出现在 sshd_config 文件中的允许用户列表中。
此文件的格式如下:
user1
user2
user..
然后,提取 sshd_config 文件中的 AllowUsers 列表并与生成的用户列表进行对比。如果有不同之处,就更新 sshd_config 文件。注意,列表包含 root@tardis 的短名称和长名称。正如前面提到的,这意味着只有来自主机 tardis 的 root 用户可以通过 SSH 访问。如果 sshd_config 有任何变动,就重新启动 SSH 服务并向管理员发送电子邮件,通知 sshd_config AllowUsers 列表的变动。
此脚本假设已经存在 AllowUsers 列表条目,而且列表至少包含部署服务器的条目,比如:
AllowUsers root@tardis root@tardis.drwho.com
这是主机名, root 用户只能从这个主机连接。在此示例中,列表同时包含短主机名和长主机名(主机名是 tardis)。根据自己的需要修改脚本,把主机 tardis 替换为自己的主机。可以用您喜欢的调度程序每天运行此脚本一次,从而及时更新用户列表。
清单 . pop_user_allow_ssh
#!/bin/sh
#set -x
# pop_user_allow_ssh
# populate UserAllow entries in sshd_conf
# if rlogin is true host=$(hostname)
log=/opt/dump/ssh_pop.log
>$log if [ -f /usr/local/etc/sshd_config ]
then
sshd_conf="/usr/local/etc/sshd_config"
fi if [ -f /etc/ssh/sshd_config ]
then
sshd_conf="/etc/ssh/sshd_config"
fi echo " on ${host}: ssh config to use: [$sshd_conf]" | tee -a $log # check if we need to run..any user adds/deletes
pre=`grep -w ^AllowUsers $sshd_conf`
pre=$(echo $pre | sed s/root@tardis.drwho.com//g |sed
s/root@tardis//g|sed s/AllowUsers//g)
curr=$(lsuser -a rlogin ALL |grep true| grep -v root| awk '{print $1}') # check for ignores - do NOT add to allow list
if [ -f /tmp/ssh_ignore ]
then
cat /tmp/ssh_ignore|while read user
do
new_curr=$(echo $curr | tr ' ' '\n' | grep -v '^'$user'$' | tr '\n' ' ')
echo "[$user]"
curr=$new_curr done
fi
echo "curr [$curr]"
echo "pre [$pre]" echo $curr >/tmp/curr.txt
echo $pre >/tmp/pre.txt
diff /tmp/curr.txt /tmp/pre.txt >&
if [ $? = ]
then
echo "no user adds/deletes detected on system"| tee -a $log
exit
else
echo "changes detected..re-populating" |tee -a $log
fi cp $sshd_conf $sshd_conf.bak sed '/AllowUsers/d' $sshd_conf >$sshd_conf.$$
echo "AllowUsers root@tardis root@tardis.drwho.com" $curr >>$sshd_conf.$$
mv $sshd_conf.$$ $sshd_conf
stopsrc -s sshd
sleep
startsrc -s sshd # next determine change and email out change
>/tmp/curr.txt2
>/tmp/pre.txt2
cat /tmp/curr.txt|tr " " "\n" |
while read name
do
echo $name >>/tmp/curr.txt2
done cat /tmp/pre.txt| tr " " "\n" |
while read name
do
echo $name >>/tmp/pre.txt2
done diff /tmp/pre.txt2 /tmp/curr.txt2 >/tmp/allow_diff.txt
changelist=$(cat /tmp/allow_diff.txt | egrep "<|>" | sed 's/[<>]//g') list="admins@drwho.com" mail -s "`hostname` allowed users sshd_config change" $list <<mayday
Host: `hostname`
SSH: $sshd_conf
The following users have been either added or deleted in AllowUsers: $changelist mayday
回页首
调试
要启用调试,消息文件提供的信息是不够的。在客户端,可以在通过 SSH 连接时使用详细(v)选项,v 越多,输出越详细:
ssh -vv -l <login> <hostname>
在服务器端,停止 sshd 服务,然后带调试选项启动它。调试(d)意味着输出更详细。在进行连接时,sshd 将终止。然后需要在调试模式下再次重新启动它(如果需要进一步测试的话),或者通过 startsrc 命令以正常方式重新启动它。使用以下命令在调试模式下启动:
# /usr/sbin/sshd -dd
如果在尝试通过 SSH 连接时发现了问题,而且问题的原因不明,那么我建议同时使用客户机和服务器调试方法诊断问题。
在调试模式下启动 sshd 的典型输出如下:
# /usr/sbin/sshd -dd
debug2: load_server_config: filename /etc/ssh/sshd_config
debug2: load_server_config: done config len =
debug2: parse_server_config: config /etc/ssh/sshd_config len
debug1: sshd version OpenSSH_5.0p1
debug1: read PEM private key done: type RSA
debug1: private host key: # type RSA
debug1: read PEM private key done: type DSA
debug1: private host key: # type DSA
debug1: rexec_argv[]='/usr/sbin/sshd'
…..
debug2: parse_server_config: config reprocess config len
User bravo from rs6000 not allowed because listed in DenyUsers
input_userauth_request: invalid user bravo
如果在调试模式下启动 sshd,会在标准输出中报告 sshd 在 sshd_conf 中找到的错误。如果用 startsrc 命令启动 sshd,在 sshd_conf 中找到的错误会显示在 /var/adm/messages 文件中。还可以使用以下方法检查最后存在的状态(可以判断配置是否有问题):
# /usr/sbin/ssh -t
# echo $?
但是,在诊断与 SSH 相关的问题时,应该首先使用调试方法。
SSH 限制的更多相关文章
- [linux]阿里云主机的免登陆安全SSH配置与思考
公司服务器使用的第三方云端服务,即阿里云,而本地需要经常去登录到服务器做相应的配置工作,鉴于此,每次登录都要使用密码是比较烦躁的,本着极速思想,我们需要配置我们的免登陆. 一 理论概述 SSH介绍 S ...
- SSH实战 · 唯唯乐购项目(上)
前台需求分析 一:用户模块 注册 前台JS校验 使用AJAX完成对用户名(邮箱)的异步校验 后台Struts2校验 验证码 发送激活邮件 将用户信息存入到数据库 激活 点击激活邮件中的链接完成激活 根 ...
- 记录一则Linux SSH的互信配置过程
需求:四台Linux主机,IP地址为192.168.10.10/11/12/13,配置登录用户的互信 1.各节点ssh-keygen生成RSA密钥和公钥 ssh-keygen -q -t rsa -N ...
- SSH免手动输入密码和设置代理
通过使用sshpass将密码写入命令里,直接执行,免去手动密码输入的步骤命令如下: sshpass -p password_abc ssh user_abc@ssh_host -p ssh_port ...
- github免输用户名/密码SSH登录的配置
从github上获取的,自己整理了下,以备后用. Generating an SSH key mac windows SSH keys are a way to identify trusted co ...
- Linux 利用Google Authenticator实现ssh登录双因素认证
1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...
- mac下生成ssh keys 并上传github仓储
使用github仓储需要本机生成一个公钥key 添加到自己的git账户SSH keys中 mac 生成方法: 1. 打开终端 输入 ssh-keygen 然后系统提示输入文件保存位置等信息 ...
- Linux实战教学笔记05:远程SSH连接服务与基本排错(新手扫盲篇)
第五节 远程SSH连接服务与基本排错 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 远程连接LInux系统管理 1.1 为什么要远程连接Linux系统 在实际的工作场景中,虚拟机界面或物理 ...
- 树莓派3B的食用方法-1(装系统 网线ssh连接)
首先要有一个树莓派3B , 在某宝买就行, 这东西基本上找到假货都难,另外国产和英国也没什么差别,差不多哪个便宜买哪个就行. 不要买店家的套餐,一个是配的东西有些不需要,有的质量也不好. 提示:除了G ...
- linux启动SSH及开机自动启动
本文地址 分享提纲: 1.查看是否启动 2. 设置自动启动 1.[查看是否启动] 启动SSH服务 “/etc/init.d/sshd start”.然后用netstat -antulp | grep ...
随机推荐
- oracle全文索引的创建和使用
整理一下我所遇到过的有关全文索引的问题吧 一.设置词法分析器 Oracle实现全文检索,其机制其实很简单.即通过Oracle专利的词法分析器(lexer),将文章中所有的表意单元(Oracle 称为 ...
- [Linux] Ubuntu下的文件比较工具--meld
在ubuntu中需要比较文件的差异,于是安装meld apt-get install meld 安装完后,在/usr/bin/下找到meld,然后发送到桌面上, 或者在命令行执行meld命令 打开后选 ...
- vim配置总结
本博文转自:http://www.cppblog.com/runsisi/archive/2013/04/06/199152.html? opt=admin 12年的最后一天配置了一下公司RHEL上的 ...
- ZeroMQZeroMQ研究与应用分析
1 ZeroMQ概述 ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字.ZeroMQ是网络通信中新的一层,介于应用 ...
- ActiveX 控件漏洞挖掘之方法
ActiveX是微软公司提出,并在1996年被正式命名的组件技术.该技术提供了一种通用的开放程序接口,使用这种技术开发的ActiveX控件可以直接集成到IE浏览器或第三方应用程序中,但由于第三方编程等 ...
- 【云计算】Docker 镜像如何设置语言环境?bash: warning: setlocale: LC_ALL: cannot change locale (en_US)
解决方案: # set default language environment RUN locale-gen en_US.UTF- \ && dpkg-reconfigure loc ...
- 走进C++程序世界------异常处理
一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制. C++的异常情况无非两种,一种是语法错误.即程序中出现了错误的语句,函数.结构和类,致使编译程序无法进行.还有 ...
- <The Art of Readable Code> 笔记一
第1章 代码应易理解 (Code should be easy to understand) 基本原则:好的代码,能够减少 “别人” 理解它的时间. “别人” 不仅指的是 “其它人”,也可能是 “以 ...
- 使用System.getProperty方法,如何配置JVM系统属性 (转载)
很多时候需要在项目中读取外部属性文件,用到了System.getProperty("")方法.这个方法需要配置JVM系统属性,那么如何配置呢? 那就是使用java -D 配置系统属 ...
- Object.defineProperty 监听对象属性变化
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...