2018年04月13日 更新,添加了 fail2ban 进阶配置教程链接,更新了命令。
落格博客全站迁移到了 vultr,每月最低只要 15块人民币,支持我的话考虑用我的邀请码注册,还送 $10 (合 60 多块人民币) 优惠!😚
最近路由购买了一台vps用来学习……是的!你没有看错!我真的是用来认真的学习的!
=。=
总之,在购买了一台vps之后,你总是需要做足一些基础的安全措施来保证你的vps不会沦为某些傻逼的肉鸡。
好吧,这次因为我购买的是一台Linux系统的vps,那么我就以这个为栗子来进行记录了。
由于一台vps就相当于一台拥有独立IP的,直接暴露于互联网之上的电脑,这在为你带来便利的同时也直接让你的vps与危险画上了等号,密码穷举、DDOS攻击、各种各样你想到的想不到的攻击方法都在等待着你,不要相信你那惊悚的创意能想出多么强大的密码,统计学告诉我们——还是相信RSA吧!
使用RSA密钥对登陆SSH
首先就来说一下SSH密码穷举的问题——别告诉我你还在telnet,否则我们没得聊,请立即关闭这个页面!
这个世界上,总有不少的傻逼在无聊的做着SSH弱口令扫描这种事情,相信我,你比不过字典。所以,关闭SSH的密码验证是一个不错的选择。
以前我们老师就讲:其实最安全的电脑反而是那些没有密码的电脑,没有密码也就无从破解——因为系统会拒绝远程登录。
可是关闭了SSH密码验证怎么登录呢?vnc?不,不。我们可以使用RSA密钥对。
通过生成RSA公私密钥对,将公钥上传到服务器,自己保留私钥,这样不仅加强了密码,更带来了不需要密码就能登录的便利①
①:不需要密码是一种选择,路由推荐各位还是在此基础上依旧使用一个密码,这样即使有人得到了你的私钥备份,也不太容易免密码登录你的vps了。
按照如下示例来使用命令:ssh-keygen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
logcg.com:~ r0uter$ ssh-keygen -b 2048 -t rsa //ssh-keygen是命令 //-b后边接要采用的字节长度;一般为1024,最短也要768,我采用了2048;变态一点你可以选择4096,但相信我,2048已经明显感觉会延迟一会儿才能计算完毕了。 //-t即为加密的方式,我们选择RSA,还有其他的这里略过不讲。 Generating public/private rsa key pair. //提示正在生成密钥对 Enter file in which to save the key (/Users/r0uter/.ssh/id_rsa): //接下来输入两次你的密码;①留空按回车则为免密码登录啦! Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/r0uter/.ssh/id_rsa. Your public key has been saved in /Users/r0uter/.ssh/id_rsa.pub. The key fingerprint is://你的key指纹 e0:e0:f0:40:8d:0f:c0:e0:00:12:c8:00:1e:fc:1d:4f r0uter@logcg.com The key's randomart image is: +--[ RSA 2048]----+ | | | | |.. . . | |.o0 .. 0 . | |.o0000000 | | . ..0000 . | | .00000 | | 000000 | | 00000 | +-----------------+ |
当然了,命令反馈中的一些必要内容我已经给涂鸦过了,你大概看着差不多就对了。
接下来,我们再使用scp命令,将生成好的公钥扔到服务器上去:
1 2 |
r0uter$ scp .ssh/id_rsa.pub root@你的vps域名或者ip:/root/ //这里会要求你的SSH密码 |
的还是SSH到服务器上,把这个 id_rsa.pub 文件复制到ssh的相应目录里,然后改名为 authorized_keys
要注意的是,你想要这对密钥登录哪个账户,就放到哪个账户下,比如我要自动登录root,那么我就会这样做:
1 2 3 4 5 6 |
mkdir ~/.ssh //如果当前用户目录下没有 .ssh 目录,就先创建目录 chmod 700 ~/.ssh mv id_rsa.pub ~/.ssh cd .ssh mv id_rsa.pub authorized_keys chmod 600 authorized_keys |
这些简单的目录文件操作我就不再过多做解释了大致就是将 id_rsa.pub 改名并且放到ssh的用户配置目录里,当然,因为我这里是新系统,所以直接就改名了,你要是目录中本身就已经有了 authorized_keys 这个文件,那你就需要备份原文件或者直接将 id_rsa.pub 的内容追加到里边去。
这样,我们就已经可以使用RSA密钥文件来登录ssh了。
关闭ssh的密码登录
1 |
/etc/ssh/sshd_config |
在如上目录找到ssh服务的配置文件,将如下字段进行修改:
1 2 3 4 5 |
#PasswordAuthentication yes //修改为如下内容: PasswordAuthentication no //使用命令重启ssh服务: /etc/init.d/ssh restart |
对了, id_rsa 这个文件我建议你也拷出来额外备份,它就是你电脑上要保存的私钥,一旦丢了,你可能就需要vnc上你的vps来重置ssh啦!
另外,为了避免Write failed: Broken pipe错误,你也可以顺便在这个文档末尾加上下面一条命令,然后再重启 ssh 服务。
1 |
ClientAliveInterval 60 |
这样,你的vps很大程度上就比较安全了,不过,如果你的vps用来做网站了,开启了httpd之类的服务,那可能你还需要
安装 CSF 防火墙
通过安装csf防火墙,可以有效的屏蔽尝试入侵你vps的IP,进阶的配置我们也不需要知道,但至少你应该安装它。
使用 CSF 防火墙,我专门写了一篇文章来指导你安装并配置它,这和 ufw 冲突,如果你决定使用 csf,就忽略本文中的 ufw 相关部分即可。
安装 fail2ban 软件
这个软件将通过使用 iptables 防火墙,将尝试爆破 ssh 密码的 IP 封停,默认10分钟,这样可以有效防止攻击。
1 |
apt install fail2ban |
如果你和我一样使用 nginx 来提供服务,那么你也可以考虑进阶配置一下 fail2ban 来让它进一步保护 nginx Fail2Ban 高级配置 保护 Nginx 服务
禁用Linux多余端口
禁用掉所有端口,只留下需要使用的端口永远都是正确的选择:
使用如下命令来检测是否存在 ufw,不再推荐直接编辑 iptables 了,这东西不是一般人玩得转的,所以 Ubuntu 官方也推出了一个更简单易用的 iptables 前端来供一般管理员使用,其实功能也挺强大,但是命令精简了不少?,具体介绍请移步:Ubuntu 下更简单的防火墙 Uncomplicated Firewall
1 |
ufw status |
如果终端显示防火墙未激活(理论上都应该是这样,因为 ufw 是系统内置的。)
我们使用如下命令来添加规则:
1 2 3 4 5 6 7 8 9 10 |
ufw allow ssh ufw allow http ufw allow https //你也可以使用端口来开启 ufw allow 53 //请务必开启 ssh 端口,如果你不是标准端口,请记得开启,否则后果自负! ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y //会提示你影响ssh 连接,但只要提前加入了规则,就不会影响。 |
你看,命令多简单?用什么添加什么。它也会默认打开一些端口比如说 ICMP。
另外,它会默认设置 iptables 的 INPUT 表为拒绝,方便安全。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
iptables -F //清空配置 iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT //ssh端口打开 iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A INPUT -p udp --sport 53 -j ACCEPT //dns端口打开 iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT //本地回环总得打开吧 iptables -A INPUT -p tcp -s 0/0 --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT iptables -A INPUT -p tcp -s 0/0 --dport 443 -j ACCEPT iptables -A OUTPUT -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT //http常用端口打开 iptables-save > /etc/iptables.up.rules //保存配置文件 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT //如果上边的配置你不用,至少要执行这条命令; //上面一条命令的作用是把正在活动的连接写成配置加入防火墙 iptables -P INPUT DROP //设置其他 INPUT 流量为拒绝 iptables -L //使更改后的配置生效——重新加载配置。 |
这样,将来你要使用什么服务,就照猫画虎往里边添加什么端口就好了,额外的端口用不到开了也没用还容易被扫端口被黑=。=
对了!记得使用如下命令来导出配置,然后配置启动加载,否则一会儿各种规则就消失不见啦!
还有,不要找 iptables 的重启命令了——这玩意儿在 ubuntu 里已经是内核级别——也就是说,是实时加载生效哒!
1 2 3 4 5 6 7 8 9 |
iptables-save > /etc/iptables.up.rules //导出配置,以后可以直接编辑; iptables-restore < /etc/iptables.up.rules //导入配置,编辑之后就可以导入立即生效! //编辑/etc/network/interfaces文件来添加启动配置 auto eth0 iface eth0 inet dhcp pre-up iptables-restore < /etc/iptables.up.rules //最后这一条就是要添加进的命令! |
添加中文环境配置(选)
如果你使用的是国内的 vps,那你可能还需要修改 ubuntu 的更新源为国内镜像源,可以移步阿里云 Ubuntu 更新镜像源
在更新之后,你很可能会遇到 locale 为空的报错,那么安装一下语言环境:
1 |
apt-get install language-pack-zh-hans language-pack-zh-hans-base |
总结
这样一来,你关闭了ssh密码验证,安装了反入侵防火墙,还关闭了所有不常用端口,还利用脚本保护了 nginx 服务器……理论上你的vps至少跳出了容易被抓的肉鸡行列,后续的安全配置,就可以根据需求大家各自定制啦!
本文由 落格博客 原创撰写:落格博客 » 购买了VPS之后你应该做足的安全措施
转载请保留出处和原文链接:https://www.logcg.com/archives/884.html
我再研究下,谢谢你了
关闭密码登录后,再次连接提示:Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
也关闭了SELinux,不知道咋回事,试了好几次,求大神分析下
尝试在 /etc/ssh/ssh_config 文件中添加你的私钥名,比如说 IdentityFile ~/.ssh/id_rsa.somecomputer
默认就有了
那就尝试重新配置一下证书吧,可能是由于两端不匹配造成的,如果确定排除这个问题,那我也没辙了,毕竟我没遇到过这个问题。 :)
SFTP用证私钥可以登录
那应该是你的私钥格式问题吧,可能ssh读不出来之类,检查下编码,就我自己来说,sftp客户端和ssh用的私钥的格式是不同的,它们并不通用。
R0uter你好,我是surveillance104.
其實關於傳送ssh public key 可以通过cat命令一步搞定:
cat .ssh/id_rsa.pub | ssh root@ip address “cat >> ~/.ssh/authorized_keys”
//id_rsa.pub其實也可以是其他名字 我建議通過數字編號(比如說id_rsa0.pub)因為如果你控制兩個或兩個以上的vps管理的話//
當然如果沒有.ssh文件夾的話可以這樣:
mkdir .ssh
關於其他安全提示我已經學到了 非常感謝R0uter的教學
注意cat命令的引號是 “‘ 而不是 “” 這個我手滑打錯了 抱歉
你这个命令相当于用ssh把公钥的内容用文本的形式传给了服务器然后执行;我的命令是用scp将文件拷贝到远程服务器,其实scp也可以顺便拷贝成 authorized_keys文件名,这样的话如果写清楚路径,那也是一句话,还避免了管道的使用。其实是殊途同归的。
区别还是有的:你的一句话方便复制却不方便手打,一旦手滑,就容易打错,而用scp则少了一些符号的使用,从命中率上来讲,还是我的方法更合适
;)