Jul 10, 2016 from—http://hankerzheng.com/blog/basic-vps-security-setting
前言
开了一个Linode VPS之后, 按着Linode的教程对服务器的安全性能进行一些配置, 写一篇博客, 对配置的过程进行一些记录, 以备今后查看. Linode原文教程请点击这里
本文的方法适用于Ubuntu 16.04
创建一个权限有限的新用户
输入adduser user_name
指令, 创建一个名为user_name
的新用户, 然后为该用户设定密码
如果不做说明, 系统会创建一个和该用户同名的用户组, 如果需要修改该用户的用户组, 可以使用usermod -G group_name user_name
, 该指令会强行把名为user_name
的用户的用户组设定为group_name
. 也就是说, 在执行这个指令之后, 该用户只属于group_name
. 如果想保留用户原用户组, 可以使用-a
(append)参数, 即usermod -a -G group_name user_name
给新用户设置sudoer
退出root账户登录, 采用新建的用户登录. 如果该新用户想执行root权限下的指令, 如adduser
, usermod
等, 有这几种种方法. 一是执行su
指令, 在输入root
密码后, 将当前用户切换到root; 二是执行sudo COMMAND
指令; 或者可以用类似的su -c COMMAND root
指令, 在使用root
执行完COMMAND后, 马上切回到当前用户.
因为使用sudo
指令可以不需要输入root
密码, 而只需要当前用户密码即可, 这里推荐使用sudo
指令来执行root
权限的指令.
但是在试了sudo COMMAND
指令后, 系统跳出提示
XXX is not in the sudoers file. This incident will be reported.
这说明当前的用户并不在sudoer中. 要添加用户到sudoer可以用visudo
指令来编辑sudoers.tmp
文件. 打开后我们可以看到如下内容
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
看到root ALL=(ALL:ALL) ALL
这一行, 其中第一个ALL
指的是主机地址, 第二个ALL:ALL
指的是用户以什么身份执行, 最后一个ALL
指的是可以使用的指令
这篇文章很好地解释了该如何配置sudoer文件, 关键内容摘录如下:
##如何让普通用户support只能在某几台服务器上,执行root能执行的某些命令?
首先需要配置一些Alias,这样在下面配置权限时,会方便一些,不用写大段大段的配置。Alias主要分成4种: Host_Alias, Cmnd_Alias, User_Alias, Runas_Alias.
1) 配置Host_Alias:就是主机的列表
Host_Alias HOST_FLAG = hostname1, hostname2, hostname3
2) 配置Cmnd_Alias:就是允许执行的命令的列表
Cmnd_Alias COMMAND_FLAG = command1, command2, command3
3) 配置User_Alias:就是具有sudo权限的用户的列表
User_Alias USER_FLAG = user1, user2, user3
4) 配置Runas_Alias:就是用户以什么身份执行(例如root,或者oracle)的列表
Runas_Alias RUNAS_FLAG = operator1, operator2, operator3
5) 配置权限
配置权限的格式如下:
USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
如果不需要密码验证的话,则按照这样的格式来配置
USER_FLAG HOST_FLAG=(RUNAS_FLAG) NOPASSWD: COMMAND_FLAG
设置完成后保存并退出该文件即可.
巩固SSH登录接口
我们一般采用ssh登录Linode服务器, 但是普通密码很容易就会被暴力方法攻破. 这里我们介绍密钥对登录ssh的方法, 从而巩固ssh登录的安全性能.
首先, 根据本文的方法本地创建密4096-bit RSA钥对
然后, 将公钥上传到服务器/home/user_name/.ssh/authorized_keys
文件中. 为了安全起见, 使用sudo chmod 600 authroized_keys
指令将该文件的权限修改为仅对root
读写.
最后, 在putty客户端上的ssh中选中刚才生成的私钥.
这样一番设置后, 在此登录时, 我们只需要输入创建密钥对时的
passphrase
就可以完成用户登录了.SSH Daemon配置
禁止通过ssh登录root账户
修改/etc/ssh/sshd_config
文件, 将PermitRootLogin修改为no.
禁止所有用户通过ssh密码登录
修改/etc/ssh/sshd_config
文件, 将PasswordAuthentication修改为no.
如果应用了这条, 那么所有用户都必须要使用密钥登录.
只对一种网络协议进行监听
Daemon默认对IPv4和IPv6两种协议都进行监听. 如果用户没有两种需求, 可以关闭对一个协议的监听. 这个关闭只是对SSH Daemon而言, 并不影响网络访问. 这个修改可以通过在/etc/ssh/sshd_config
文件中添加AddressFamily inet
来实现只对IPv4的监听, 添加AddressFamily inet6
来实现只对IPv6的监听
重启SSH服务以更新配置
sudu systemctl restart sshd
安装Fail2Ban
Fail2Ban是一个能够封禁输入密码错误次数过多用户IP的软件. 该软件可以监控多种协议登录, 例如HTTP, SSH, SMTP. 默认情况下, Fail2Ban只监控SSH协议. 具体安装过程, 请看这篇文章
配置防火墙
此处我们介绍一种网络流量控制器iptables
, 它一般都会集成在Linux系统中.
UFW是一个Ubuntu系统自带的iptables控制器(准确地说, UFW是iptables的图形界面), 如果想直接使用用UFW, 可以看这篇文章
查看当前iptables
规则
查看IPv4规则的指令为sudo iptables -L
, 查看IPv6规则的指令为sudo ip6tables -L
默认的iptables没有应用任何规则, 在新建的Linode系统中, 我们一般能看到下面的防火墙规则, 分别表示所有的流入, 流出, 以及换发流量都是允许的.
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
IPtables基本规则设置
下面的配置内容只是Linode给出的参考, 具体的设置可以参考这篇文章
设置IPv4过滤过则, 打开文件/tmp/v4
, 输入以下内容:
*filter
# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT
# Allow ping.
-A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT
# Allow SSH connections.
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere
# (the normal ports for web servers).
-A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
# Allow inbound traffic from established connections.
# This includes ICMP error returns.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Log what was incoming but denied (optional but useful).
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables_INPUT_denied: " --log-level 7
# Reject all other inbound.
-A INPUT -j REJECT
# Log any traffic that was sent to you
# for forwarding (optional but useful).
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables_FORWARD_denied: " --log-level 7
# Reject all traffic forwarding.
-A FORWARD -j REJECT
COMMIT
如果希望启用Linode Longview或者Linode NodeBalancers, 需要在HTTP, HTTPS过滤过则那一栏加入以下规则:
# Allow incoming Longview connections.
-A INPUT -s longview.linode.com -m state --state NEW -j ACCEPT
# Allow incoming NodeBalancer connections.
-A INPUT -s 192.168.255.0/24 -m state --state NEW -j ACCEPT
同样的, 对IPv6的过滤过则设置, 打开文件/tmp/v6
, 输入一下内容
*filter
# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s ::1/128 -j REJECT
# Allow ICMP
-A INPUT -p icmpv6 -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere
# (the normal ports for web servers).
-A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT
# Allow inbound traffic from established connections.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Log what was incoming but denied (optional but useful).
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "ip6tables_INPUT_denied: " --log-level 7
# Reject all other inbound.
-A INPUT -j REJECT
# Log any traffic that was sent to you
# for forwarding (optional but useful).
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "ip6tables_FORWARD_denied: " --log-level 7
# Reject all traffic forwarding.
-A FORWARD -j REJECT
COMMIT
apt-get
指令会通过IPv6来解析资源镜像的域名. 如果防火墙设置为完全关闭IPv6, 这会导致Ubuntu更新变得很慢. 这个问题可以通过去掉文件/etc/gai.conf
里面preecedence ::ffff:0:0/96 100
这句话前面的注释号解决
应用防火墙规则(Ubuntu)
使用下面指令来应用配置的iptables过滤过则:
sudo iptables-restore < /tmp/v4
sudo ip6tables-restore < /tmp/v6
iptables-persistent
能在系统启动的时候自动加载iptables规则, 建议安装. 安装指令为sudo apt-get install iptables-persistent
. 安装完成后, iptables-persistent会弹出窗口询问是否要保存当前的iptables规则, 选择yes.
最后, 删除iptables配置的临时文件sudo rm /tmp/{v4,v6}
确认当前iptables规则
指令sudo iptables -vL
以及sudo ip6tables -vL
能查看当前防火墙的过滤规则.
修改iptables规则
iptables规则被强制设计成从上往下的形式, 也就是说数据包在被iptables过滤的时候, 是一次次按照顺序分别通过每一个规则的, 所以才称之为iptables Chain(链). 因此, 添加规则时, 不能使用iptables -A
或者ip6tables -A
指令, 而应该使用iptables -I
或者ip6tables -I
指令
插入规则
插入规则时, 需要指明规则插入的位置. 可以执行sudo iptables -L --line-numbers
指令得到当前过滤规则的列表. 加入我们需要添加Linode Longview连接, 并且将该规则的顺序设定为INPUT Chain的8, 我们只需要输入sudo iptables -I INPUT 8 -p tcp -dport 8080 -j ACCEPT
替换规则
sudo iptables -R INPUT 9 -m limit --limit 3/min -j LOG --log-prefix "iptables_INPUT_denied: " --log-level 7
删除规则
sudo iptables -D INPUT 8