<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>~iany/ SSH</title><link>https://blog.iany.me/zh/tags/ssh/</link><description>SSH的最新内容 «~iany/»</description><language>zh-CN</language><managingEditor>me@iany.me (Ian Yang)</managingEditor><webMaster>me@iany.me (Ian Yang)</webMaster><copyright>CC-BY-SA 4.0</copyright><lastBuildDate>Wed, 11 Nov 2015 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iany.me/zh/tags/ssh/index.xml" rel="self" type="application/rss+xml"/><item><title>从 Redis 攻击例子谈谈基本的 Linux 服务器安全</title><link>https://blog.iany.me/zh/2015/11/linux-server-security-intro-after-redis-attached/</link><pubDate>Wed, 11 Nov 2015 00:00:00 +0000</pubDate><author>me@iany.me (Ian Yang)</author><guid>https://blog.iany.me/zh/2015/11/linux-server-security-intro-after-redis-attached/</guid><description>&lt;p&gt;最近看到一篇文章详细说明了&lt;a href="http://www.antirez.com/news/96"&gt;如何通过 Redis 获得 SSH 登录权限&lt;/a&gt;。简单来说就是如果 Redis 开放了外网端口访问，又没配置防火墙，也没有配置任何 Redis 的连接验证，而且还是用很高权限的用户在运行 Redis，就可以通过 dump 数据库把任意 key 注入到 &lt;code&gt;authorized_keys&lt;/code&gt; 文件中，从而获得用户的 SSH 登录权限。条件很苛刻，但是很容易自动化，估计还是可以扫描到不少肉鸡的。&lt;/p&gt;
&lt;p&gt;比较惭愧，最近部署的一台服务器就被该方法攻击了。主要原因是之前我已经书面说明了防火墙如何配置，所以想当然的认为拿到的机器已经配置好了。为了让 Redis 在内网内能访问，配置脚本中将监听的地址改成了 0.0.0.0，也没有配置连接验证，结果就是任何人都能连接上这个数据库。不过因为还是用的单独的 redis 用户运行，权限有限，攻击者并没有拿到 SSH 登录权限，只是把数据库清空了。所幸是测试服务器，数据库中的数据并不重要。&lt;/p&gt;
&lt;p&gt;下面说明下我所了解的保护服务器安全的一些常识。&lt;/p&gt;
&lt;h2 id="禁止密码登录"&gt;禁止密码登录&lt;/h2&gt;
&lt;p&gt;只使用密码是不安全的。尤其是高权限用户，比如 root，无时无刻都有人在尝试暴力破解密码。不要以为改个 SSH 端口号就安全了，通过端口扫描很容易就能发现 SSH 端口。这个可以在 &lt;code&gt;sshd_config&lt;/code&gt; 里禁止所有用户使用密码登录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PasswordAuthentication no
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置完重启 SSH 之前记得先确认可以通过钥匙对登录，不然就要悲剧了。&lt;/p&gt;
&lt;h2 id="保护好私钥"&gt;保护好私钥&lt;/h2&gt;
&lt;p&gt;添加 passphrase。因为有 ssh agent，基本上只需要登录后输入一次就行了。这样做主要是保证设备遗失后有充足的时间从服务器上的 &lt;code&gt;authorized_keys&lt;/code&gt; 里删除对应的公钥。&lt;/p&gt;
&lt;p&gt;在每台设备上单独生成不同的钥匙对，这样一台机器遗失只需要作废对应的公钥。尤其不要多个用户共享一个私钥。&lt;/p&gt;
&lt;p&gt;重要的账号最好单独生成一对钥匙对，比如某机房中所有机器的最高权限管理账号。&lt;/p&gt;
&lt;h2 id="保护好公钥"&gt;保护好公钥&lt;/h2&gt;
&lt;p&gt;这个是指保护好 &lt;code&gt;authorized_keys&lt;/code&gt; 文件。OpenSSH 默认就有强制的要求，在 &lt;code&gt;.ssh&lt;/code&gt; 目录或者 &lt;code&gt;authorized_keys&lt;/code&gt; 权限不正确的情况下都会忽略文件中的公钥。如果想更好的保护，可以使用 &lt;a href="https://wiki.archlinux.org/index.php/Access_Control_Lists"&gt;chatter&lt;/a&gt; 把 &lt;code&gt;.ssh&lt;/code&gt; 和 &lt;code&gt;authorized_keys&lt;/code&gt; 都标记成只读，在共享某个账号时防止被任意修改。标记 &lt;code&gt;.ssh&lt;/code&gt; 是为了防止删除整个目录重新创建。注意先创建 &lt;code&gt;known_hosts&lt;/code&gt;，不然 &lt;code&gt;.ssh&lt;/code&gt; 标记成只读后就没办法添加新文件了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;touch ~/.ssh/known_hosts
sudo chattr +i ~/.ssh ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在需要修改的时候，先用 &lt;code&gt;chattr -i&lt;/code&gt; 取消掉只读。&lt;/p&gt;
&lt;h2 id="不要直接使用-root-用户"&gt;不要直接使用 root 用户&lt;/h2&gt;
&lt;p&gt;配置一个有 sudo 权限的用户来管理服务器。哪怕是不需要密码就可以 sudo 也比直接用 root 安全得多，因为你可以选择哪些命令 sudo 哪些不 sudo，而 root 所有的命令都是最高权限，需要时刻提心吊胆。&lt;/p&gt;
&lt;p&gt;同时也可以在 &lt;code&gt;sshd_config&lt;/code&gt; 是禁止 root 登录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PermitRootLogin yes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="使用专门的用户来运行后台程序"&gt;使用专门的用户来运行后台程序&lt;/h2&gt;
&lt;p&gt;并且只给该用户必要的权限来进行隔离，减少该程序被攻击时对机器上其它程序的影响。比如在这次 Redis 攻击中，如果是使用 root 权限运行的，就可以通过 dir 和 dbfilename 两个配置覆盖任何文件，而如果使用专门的 redis 用户，就只能是在 redis 用户有写权限的地方了。大部分包管理器安装的后台程序都会使用专门的用户来运行。要注意的是在自己编译安装服务时，一定不能嫌麻烦。&lt;/p&gt;
&lt;h2 id="配置防火墙"&gt;配置防火墙&lt;/h2&gt;
&lt;p&gt;只允许必要的端口被外网访问。在 Ubuntu 上，&lt;a href="https://wiki.ubuntu.com/UncomplicatedFirewall"&gt;ufw&lt;/a&gt; 使用起来已经相当方便了，这次被攻击后也是使用 &lt;code&gt;ufw&lt;/code&gt; 添加了防火墙。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ufw allow ssh/tcp
sudo ufw allow http/tcp
sudo utw enable
&lt;/code&gt;&lt;/pre&gt;</description><category domain="https://blog.iany.me/zh/">~iany/</category><category domain="https://blog.iany.me/zh/tags/linux/">Linux</category><category domain="https://blog.iany.me/zh/tags/redis/">Redis</category><category domain="https://blog.iany.me/zh/tags/security/">Security</category><category domain="https://blog.iany.me/zh/tags/ssh/">SSH</category></item></channel></rss>