GNU/Linux 安全 tips
Table of Contents
1. 说明
本文总结一些 GNU/Linux 安全相关的通用技能。
开源不意味着安全,不过一旦爆光出漏洞,会有全世界的贡献协助快速修复漏洞。
2. 基本安全原则
- 最小化安装
- 最小化服务
- 使用加密传输,如 FTP -> SFTP、HTTP -> HTTPS、Telnet -> SSH、SNMP v1/v2 -> SNMP v3
- 重要数据也加密存储
- 不直接使用 root 帐号,原因:1) 防止 root 帐号被泄露;2) 需要 root 时再使用 sudo,便于审计用多种验证方式,如指纹、OTP
- 防火墙
- 日志监控
3. GNU/Linux 发行版选择
一个发行版要做到安全和稳定,并且软件包丰富,是需要投入大量的人力,这不是一般小组织可以搞定的。所以无论是作为服务器系统,或是个人桌面,都得优先选用成熟的发行版。
可以从很多角度判断一个系统是否成熟,例如:
- 社区活跃度
- 是否有商业公司的支持
- 用户量
- 发行版对待安全的态度
- 更新频率,有些是半年发布一个版本,有些是滚动更新,有些甚至连发行周期都不知道
推荐的发型版:
- 红帽系列:Fedora、RHEL/CentOS
- Debian
- SUSE/openSUSE
- Arch Linux,推荐基于 Arch 的 Manjaro
成熟的发行版有集中的包管理,可以通过系统自带的包管理器对软件和系统升级。Windows软件通常是从三方网站下载安装。
4. 磁盘分区
4.1. 任何用户可写的目录,挂载到独立的分区上
- /tmp 独立为一个分区,并且禁止执行程序。因为任何用户都可以在这里读写。比如 GNU/Linux 存在一个本地提权漏洞,黑客可以将 Exploit 代码放在 /tmp 下编译并执行。可以重新挂载 /tmp 并设置成不可执行文件:
mount -o remount,noexec /tmp
并在 /etc/fstab 中设置,让下次启动也生效:
/dev/sdb1 /tmp ext2 defaults,noexec 0 0
- /var/tmp 和 /tmp 设置一样,因为 /var/tmp 也可以让任何用户读写。
- 另外用户可随意读写的目录挂载到其他目录中,也可以防止用户写过大的文件影响到根分区。
5. 端口
- 谨慎监听 0.0.0.0。
- 无需外网访问、只需内网访问的端口,监听内网地址。
- 外网和内网都不需要访问的端口,监听 127.0.0.1。
- 开发环境监听端口需谨慎,因为开发中的程序不可靠、不安全,并且带有太多调试信息,只监听 127.0.0.1。
6. 系统配置
6.1. 软件设置
- 生产服务器尽量避免安装 GCC、Clang 等 C 源码编译器。因为安装 Rootkit 或者用 Exploit 提权,都需要编译代码。
- 主流发行版的软件源中包含官方源,因为出现重大漏洞后,可以及时获得官方修复补丁。
- 同类产品,优先选用安全等级较高的,比如 OpenSSL 近年来爆出太多漏洞,可考虑用 LibreSSL 代替:
$ wget http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.2.0.tar.gz $ tar xvf libressl-2.2.0.tar.gz $ cd libressl-2.2.0/ $ ./configure $ make && sudo make install $ ldconfig
6.2. lshell——受限制的 shell
只允许某个用户、某个用户组运行指定命令、进入指定目录、限制 PATH 变量等。官网:https://github.com/ghantoos/lshell
示例,只允许 test1 用户运行 ls、pwd 命令,只能访问 /etc 和 /tmp 目录。
安装后,改变要受到限制用户的默认 shell:
$ chsh test1 -s `which lshell`
然后追加以下内容到 /etc/lshell.conf
[test1] allowed :['ls', 'pwd'] path :['/etc', '/tmp'] aliases : {'ls':'ls --color'}
7. 文件安全
7.1. 特权文件
以下命令助你找到系统中的特权文件:
sudo find / -perm -4000
该去掉 s 标志位的程序可去掉,尽量保留最少。
8. 帐号安全
- 多帐号、权限分离,让不同的进程以不同的身份运行,每个服务拥有自己的帐号,每个系统用户也有自己的帐号。
- 帐号强密码。误使用弱口令(如:123456)。
- 定期巡查 /etc/shadow 哪些帐号被设置了密码,警惕陌生帐号。
8.1. 环境变量
如果想环境变量应用到系统每个账户上,可把环境变量写在 /etc/profile中。
如果不希望用户修改环境变量,可用 readonly 将变量设为只读。如:
export TMOUT=100 readonly TMOUT
8.1.1. HISTSIZE
HISTSIZE 指定保存命令历史数目。
生产服务器上应设置小一点的值,以免管理员操作服务器的历史记录泄露敏感信息。不过我的桌面系统里设置的值却很大,因为这会便于我更高效地工作。
8.1.2. TMOUT
TMOUT指定用户空闲多少秒后断开会话。个人桌面系统不建议设置此变量。
8.2. 配置 /etc/login.defs
- PASS_MAX_DAYS:密码有效期
- PASS_MIN_LEN:密码最小长度
8.3. sudo
su 提供普通用户切换到 root,或其他用户身份。如果多个用户使用 su,就必须为这些用户提供 root 密码。为了防止 root 密码泄露,以及一些控制能力,所以建议使用 sudo。
sudo 配置文件路径:/etc/sudo.conf。
- 单独存放 sudo 日志,便于日志分析。配置中加上:
Defaults logfile=/var/log/sudo.log
例,查看密码错误日志:
fgrep 'incorrect password attempts' /var/log.sudo.log
- 配置保护路径,防止环境变量被修改:
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
8.4. /bin/false 并不完美
如果要禁止某个帐号登录系统,通常会把帐号的 shell 改成 /bin/false,如:
sudo usermod -s /bin/false xiaoming
即便帐号被泄露,也无法登录系统,这种设置看上去很安全。如,192.168.77.132 这台机器上 test 帐号配置如下:
test:x:1002:1003::/home/test:/bin/false
不能登录 shell,但我们可以做端口转发,本地监听 4899 端口来做转发:
ssh -qTfnN -D 4899 [email protected]
比如 192.168.77.132 的 80 端口未对外开放,但通过这个隧道我们就能成功访问到:
$ proxychains4 curl localhost/test.php
9. OpenSSH
服务端默认配置文件:/etc/ssh/sshd_config
- 帐号登录使用证书认证,禁用密码登录:PasswordAuthentication no。一定要先确保能够用证书登录后,再设置,不然下次就登不上服务器了
- 禁止空密码:PermitEmptyPasswords no
- 限制允许/禁止登录的帐号,参考 man sshd_config 中 DenyUsers、AllowUsers、DenyGroups 和 AllowGroups 四个值
- 禁止 root 帐号登录:PermitRootLogin no
- ssh 登录系统后,可执行 /etc/ssh/sshrc 里的命令,如下,一个启动ssh会话后自动发邮件的命令:
echo "${SSH_CLIENT}登录了${USER}" | mail -s "黑客来了" [email protected]
10. 其他
10.1. 关注安全通告
关注主流安全咨询网站,以便及时获得跟系统切身相关的安全信息。
也可订阅相关发行版安全相关的邮件列表,如:
- Fedora:http://www.redhat.com/mailman/listinfo/fedora-security-list
- Debian:https://lists.debian.org/debian-security-announce/
等等。