安全是一个服务器最基本的必备条件,在创建了服务器之后,你首先要做的事情就是将服务器加固。
由于服务器就相当于一台拥有独立 IP 的、直接暴露于互联网之上的电脑,这在为你带来便利的同时也直接让你的服务器与危险画上了等号,密码穷举、DDOS 攻击、各种各样你想到的、想不到的攻击方法都在等着你。
说不定你的服务器正在被攻击!
注:本人主机为 CentOS 7 x64 系统,以下内容均基于此环境。
查看登录失败的日志
1 | COPYsudo lastb |
统计尝试暴力破解机器密码的 IP
1 | COPYsudo grep "Failed password for invalid" /var/log/secure | awk '{print $13}' | sort | uniq -c | sort -nr | more |
统计有哪些用户名尝试登录
1 | COPYsudo grep "Failed password for invalid" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more |
嗯哼,结果可怕吗?
永远不要以 root 登录服务器。
你可以新建一个用户来管理,而非直接使用 root 用户,防止密码被破解。
增加用户
1 2 | COPYuseradd -m username # -m 可以为用户创建相应的帐号和用户目录/home/username |
设置新用户密码
1 | COPYpasswd username |
将新用户加入到 Wheel 组
1 | COPYusermod -G wheel username |
限制su命令
1 2 3 4 5 6 7 | COPYvi /etc/pam.d/su # 去除下面命令的注释 #auth required pam_wheel.so use_uid # 只允许管理员组的用户执行 sh 命令 echo "SU_WHEEL_ONLY yes">>/etc/login.defs |
除去验证密码
1 2 3 | COPYvi /etc/sudoers # 在 root 下面增加 以下内容: username ALL=(ALL) NOPASSWD: ALL |
禁止 root 登陆
1 2 3 4 5 | COPYvi /etc/ssh/sshd_config PermitRootLogin no #禁止 root 登录 PermitEmptyPasswords no #禁止空密码登录 AllowUsers username #设置刚才创建的用户可以登录 |
重启服务器
1 | COPYreboot |
1 2 3 4 5 6 7 8 9 10 | COPYpasswd -l dbus passwd -l nobody passwd -l ftp passwd -l mail passwd -l shutdown passwd -l halt passwd -l operator passwd -l sync passwd -l adm passwd -l lp |
1 2 3 4 5 6 | COPYsudo chattr +i /etc/passwd sudo chattr +i /etc/shadow sudo chattr +i /etc/group sudo chattr +i /etc/gshadow sudo chmod -R 700 /etc/rc.d/init.d/* |
这样操作之后也无法创建账号和修改密码,后面可以使用chattr -i命令恢复之后再进行操作。
ssh 登陆默认的端口是22,那些扫描穷举密码的,也一定从22开始。
编辑配置文件
1 | COPYsudo vi /etc/ssh/sshd_config |
将其中的Port 22改为其他端口
port的取值范围是 0 – 65535(即 2 的 16 次方)
0 到 1024 是众所周知的端口(知名端口,常用于系统服务等,例如 http 服务的端口号是 80)
配置防火墙
1 2 3 4 | COPY#CentOS 6 中防火墙开启对应端口 iptables -I INPUT -p tcp --dport 设置的端口号 -j ACCEPT #CentOS 7 中防火墙开启对应端口 sudo firewall-cmd --zone=public --add-port=设置的端口号/tcp --permanent |
重启 sshd
1 | COPYservice sshd restart |
编辑配置文件
1 | COPYsudo vi /etc/ssh/sshd_config |
修改以下内容
1 2 3 4 | COPYChrootDirectory /home/%u X11Forwarding no AllowTcpForwarding no UseDNS no |
重启服务器
1 | COPYservice sshd restart |
如果一定要使用密码登录,请查考正文最后 fail2ban 与 DenyHosts 的介绍。
不要相信自己的密码,在暴力枚举面前,只是时间文件。
统计学告诉我们,请配置 RSA
有两种不同的密钥分发方式,但结果都是一样的。
在客户端生成公钥与私钥,上传公钥到服务器
在服务器生成公钥和私钥,复制私钥到客户端
我使用第二种方式进行演示:
服务器生成密钥
1 | COPYsudo ssh-keygen -b 2048 -t rsa |
这样一来,在根目录就生成了一个.ssh的隐藏目录,内含两个密钥文件。
xxx 为私钥,需复制到客户端,xxx.pub 为公钥。
服务器配置公钥
1 2 3 4 5 | COPYcd ~/.ssh sudo cat xxx.pub >> authorized_keys # 默认允许的 key 存储的文件 sudo chmod 600 authorized_keys sudo chmod 700 ~/.ssh |
配置 ssh 文件
1 2 3 4 5 6 | COPYsudo vi /etc/ssh/sshd_config #编辑以下内容 RSAAuthentication yes #RSA 认证 PubkeyAuthentication yes #开启公钥验证 AuthorizedKeysFile .ssh/authorized_keys #验证文件路径 |
复制私钥到本地,并且设置相应 ssh 工具的连接配置。
重启服务器
1 | COPYservice sshd restart |
禁止密码登录
使用密钥登录成功之后,再设置此项。
1 2 3 4 5 6 | COPYsudo vi /etc/ssh/sshd_config #编辑以下内容 PasswordAuthentication no #禁止密码认证 PermitEmptyPasswords no #禁止空密码 UsePAM no#禁用 PAM |
iptables 是Linux上最强大的防火墙软件。
安装
1 2 3 4 5 6 | COPYyum install iptables -y yum install iptables-services -y #CentOS7 需安装此 iptables 的 service 软件包# # Debian/Ubuntu 执行: apt-get install iptables -y apt-get install iptables-persistent -y #持久化 iptables 规则服务# |
CentOS 7 上默认安装了 firewalld 建议关闭并禁用:
1 2 | COPYsystemctl stop firewalld systemctl mask firewalld |
清除已有 iptables 规则
1 2 3 | COPYiptables -F iptables -X iptables -Z |
开发指定端口
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | COPY# 允许本地回环接口(即运行本机访问本机) iptables -A INPUT -i lo -j ACCEPT # 允许已建立的或相关连的通行 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #允许所有本机向外的访问 iptables -A OUTPUT -j ACCEPT # 允许访问 22222(SSH)端口,以下几条相同,分别是 22222,80,443 端口的访问 iptables -A INPUT -p tcp --dport 22222 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT #允许 FTP 服务的 21 和 20 端口 iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --dport 20 -j ACCEPT #如果有其他端口的话,规则也类似,稍微修改上述语句就行 #允许 ping iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT #禁止其他未允许的规则访问(注意:如果 22 端口未加入允许规则,SSH 链接会直接断开。) iptables -A INPUT -j REJECT iptables -A FORWARD -j REJECT #屏蔽单个 IP 的命令是 iptables -I INPUT -s 123.45.6.7 -j DROP #封整个段即从 123.0.0.1 到 123.255.255.254 的命令 iptables -I INPUT -s 123.0.0.0/8 -j DROP #封 IP 段即从 123.45.0.1 到 123.45.255.254 的命令 iptables -I INPUT -s 124.45.0.0/16 -j DROP #封 IP 段即从 123.45.6.1 到 123.45.6.254 的命令是 iptables -I INPUT -s 123.45.6.0/24 -j DROP #屏蔽某 IP 访问指定端口,以 22 端口为例命令是 iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j DROP #允许某 IP 访问指定端口,以 22 端口为例命令是 iptables -I INPUT -p tcp --dport 22 -j DROP iptables -I INPUT -s 123.45.6.7 -p tcp --dport 22 -j ACCEPT # ACCEPT:允许通过. LOG:记录日志信息,然后传给下一条规则继续匹配. REJECT:拒绝通过,必要时会给出提示 DROP:直接丢弃,不给出任何回应. PREROUTING:在进行路由选择前处理数据包 INPUT:处理入站的数据包 OUTPUT:处理出站的数据包 FORWARD:处理转发的数据包 POSTROUTING:在进行路由选择后处理数据包 |
保存防火墙规则
1 | COPYservice iptables save |
设置防火墙开机启动
1 2 3 4 | COPYchkconfig --level 345 iptables on # CentOS7 可执行: systemctl enable iptables |
如已经设置 禁止密码登录,可忽悠。
通过使用 iptables 防火墙,将尝试爆破 ssh 密码的 IP 封停,默认 10 分钟。
安装
1 | COPYyum install -y fail2ban |
配置
1 2 3 4 5 6 7 8 9 10 11 | COPYcp -pf /etc/fail2ban/jail.conf /etc/fail2ban/jail.local vim /etc/fail2ban/jail.local [sshd] enabled = trueport = 22222 logpath = %(sshd_log)s backend = %(sshd_backend)s filter = sshd action = iptables[name=SSH, port=22222, protocol=tcp] sendmail-whois[name=SSH, dest=root, sender=fail2ban@example.com] logpath = /var/log/secure maxretry = 3 |
如已经设置 禁止密码登录,可忽悠。
分析sshd的日志文件,当发现重复的攻击时就会记录IP到/etc/hosts.deny文件,从而达到自动屏蔽IP的功能。
和 fail2ban 一样,都是防止暴力破解密码,两者任选其一即可。
安装
1 | COPYyum install denyhosts |
配置
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 27 | COPYvi /etc/denyhosts.conf # 配置相关说明 SECURE_LOG = /var/log/secure #ssh 日志文件,系统不同,文件不相同 HOSTS_DENY = /etc/hosts.deny #控制用户登陆的文件 PURGE_DENY = #过多久后清除已经禁止的,空表示永远不解禁 BLOCK_SERVICE = sshd #禁止的服务名,如还要添加其他服务,只需添加逗号跟上相应的服务即可 DENY_THRESHOLD_INVALID = 5 #允许无效用户失败的次数 DENY_THRESHOLD_VALID = 10 #允许普通用户登陆失败的次数 DENY_THRESHOLD_ROOT = 1 #允许 root 登陆失败的次数 DENY_THRESHOLD_RESTRICTED = 1 WORK_DIR = /var/lib/denyhosts #运行目录 SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES HOSTNAME_LOOKUP=YES #是否进行域名反解析 LOCK_FILE = /var/run/denyhosts.pid #程序的进程 ID ADMIN_EMAIL = root@localhost #管理员邮件地址,它会给管理员发邮件 SMTP_HOST = localhost SMTP_PORT = 25 SMTP_FROM = DenyHosts <nobody@localhost> SMTP_SUBJECT = DenyHosts Report AGE_RESET_VALID=5d #用户的登录失败计数会在多久以后重置为 0,(h 表示小时,d 表示天,m 表示月,w 表示周,y 表示年) AGE_RESET_ROOT=25d AGE_RESET_RESTRICTED=25d AGE_RESET_INVALID=10d RESET_ON_SUCCESS = yes #如果一个 ip 登陆成功后,失败的登陆计数是否重置为 0 DAEMON_LOG = /var/log/denyhosts #自己的日志文件 DAEMON_SLEEP = 30s #当以后台方式运行时,每读一次日志文件的时间间隔。 |
启动
1 2 | COPY/etc/init.d/daemon-control start #启动 denyhosts chkconfig daemon-control on #将 denghosts 设成开机启动 |
启动命令(yum 安装,已默认配好)
1 2 3 | COPYservice denyhosts start service denyhosts stop service denyhosts status |
这两天,我完成了 CentosInit 项目,一个高度自定义的 Centos 初始化脚本。
欢迎 Star PR !
如果你想快速配置以上安全措施,请执行以下命令:
通过 curl
1 | COPYONLY_SECURE=Y sh -c "$(curl -fsSL https://tomotoes.com/Centos-init/install.sh)" |
通过 wget
1 | COPYONLY_SECURE=Y sh -c "$(wget https://tomotoes.com/Centos-init/install.sh -O -)" |
脚本功能一共分为四大类:
初始化配置(update)
1 2 3 4 5 6 7 8 9 | COPYupdateLanguage updateTime updateLanguage updateTime updateDNS updateYumSource updateHostname updateUlimit updateCoreConfig |
安装常用软件(install)
1 2 3 4 5 6 7 8 9 10 11 12 | COPYinstallCommonSoft installGit installVim installZsh installNode installNpmPackages installPython installPipPackages installDocker installNginx installCcat installShadowSocks |
配置安装后的软件(config)
1 2 3 4 5 6 7 | COPYconfigVim configZsh configGit configNode configDocker configNginx configShadowSocks |
必要的安全配置(secure)
基础项
1 2 3 4 5 | COPYdeleteOrLockUnnecessaryUsersAndGroups setPrivileges closeCtrlAltDel closeIpv6 closeSELinux |
高阶项
1 2 3 4 | COPYupdateSSHPort useKeyLogin useIptable preventCrackingPassword |
用户相关项
1 2 3 4 | COPYgetUserInfo addUser joinWheelGroup banRootLogin |
如果你想安装某一种功能( Update | Install | Config | Secure )
请参考以下案列:
1 2 3 4 5 | COPY# 在安装命令前设置 ONLY_UPDATE=Y 即可只安装 update 服务 ONLY_UPDATE=Y sh -c "$(curl -fsSL https://tomotoes.com/Centos-init/install.sh)" # Install and Config ONLY_INSTALL=Y ONLY_CONFIG=Y sh -c "$(curl -fsSL https://tomotoes.com/Centos-init/install.sh)" |
你也设置设置交互模式,在交互模式下,可高达自定义化你想使用的功能。
每执行完一项功能,都会询问你下一步。
使用功能的方法如下:
1 2 | COPY# 在安装命令前设置 INTERACTIVE=Y INTERACTIVE=Y sh -c "$(curl -fsSL https://tomotoes.com/Centos-init/install.sh)" |