Secure-Linux Linux 加固+维护+应急响应参考
文档内容仅限 Linux ,web 服务和中间件的加固内容请看
加固 大纲 文件 可疑文件 最近文件 1 2 3 find / -ctime -2 find ./ -mtime 0 -name "*.jsp" find / *.jsp -perm 4777
临时文件 配置文件 1 strings /usr/sbin/sshd | egrep '[1-9]{1,3}.[1-9]{1,3}.'
文件恢复 一点建议 : 业务系统,rm 删除后,没有立即关机,运行的系统会持续覆盖误删数据.所以对于重要数据,误删后请立即关机
foremost
1 2 3 4 5 6 apt-get install -y foremostrm -f /dev/sdb1/photo1.png foremost -t png -i /dev/sdb1
extundelete
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 apt-get install -y extundeletemkdir -p /backupdate/deldate mkfs.ext4 /dev/sdd1 mount /dev/sdd1 /backupdatecd /backupdate/deldatetouch del1.txtecho " test 1" > del1.txtmd5sum del1.txt 66fb6627dbaa37721048e4549db3224d del1.txtrm -fr /backupdate/* umount /backupdate extundelete /dev/sdd1 --inode 2 extundelete /dev/sdd1 --restore-file del1.txt extundelete /dev/sdd1 --restore-directory /backupdate/deldate extundelete /dev/sdd1 --restore-all md5sum RECOVERED_FILES/ del1.txt 66fb6627dbaa37721048e4549db3224d RECOVERED_FILES/del1.txt
ext3grep
如果被误删的文件在根分区,那么你最好重启计算机,进入单用户模式,以只读的方式挂载根分区,然后再进行恢复.
进入单用户模式后,根分区还是以读写方式 mount 的,用下面的命令,把挂载方式由读写(rw)改为只读(ro): mount -o ro,remount /
如果被删除的文件不是根分区,也可以用 unmount 的方式将该分区卸载.假设文件在分区 /dev/sda3中,该分区挂载到 /home,那么我们用下面的命令来卸载: umount /dev/sda3
当然,在卸载前要保证没有程序在访问该分区,否则卸载会失败.所以,一般推荐进入单用户模式来恢复文件.
安装
访问 https://code.google.com/archive/p/ext3grep/downloads 下载源代码,这里以 ext3grep-0.10.2.tar.gz 为例
1 2 3 4 5 6 7 yum install -y e2fsprogs yum install -y e2fsprogs-devel tar zxf ext3grep-0.10.2.tar.gzcd ./ext3grep-0.10.2 ./configure make make install
如果 make 出错,修改 src/ext3.h
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 #ifndef EXT3_H #define EXT3_H #ifdef _LINUX_EXT2_FS_H #error please include this file before any other includes of ext2fs/ext2_fs.h #endif #define s_clusters_per_group s_frags_per_group #include <ext2fs/ext2_fs.h> #define EXT3_BLOCK_SIZE EXT2_BLOCK_SIZE #define EXT3_FRAG_SIZE EXT2_FRAG_SIZE #define EXT3_BLOCKS_PER_GROUP EXT2_BLOCKS_PER_GROUP #define EXT3_INODES_PER_GROUP EXT2_INODES_PER_GROUP #define EXT3_FIRST_INO EXT2_FIRST_INO #define EXT3_INODE_SIZE EXT2_INODE_SIZE #define EXT3_BLOCK_SIZE_BITS EXT2_BLOCK_SIZE_BITS #define EXT3_DESC_PER_BLOCK EXT2_DESC_PER_BLOCK #define EXT3_DIR_ROUND EXT2_DIR_ROUND #define EXT3_DIR_REC_LEN EXT2_DIR_REC_LEN #define EXT3_FT_DIR EXT2_FT_DIR #define EXT3_FT_UNKNOWN EXT2_FT_UNKNOWN #define EXT3_FT_MAX EXT2_FT_MAX #define EXT3_MAX_BLOCK_SIZE EXT2_MAX_BLOCK_SIZE #define EXT3_NDIR_BLOCKS EXT2_NDIR_BLOCKS #define EXT3_IND_BLOCK EXT2_IND_BLOCK #define EXT3_DIND_BLOCK EXT2_DIND_BLOCK #define EXT3_TIND_BLOCK EXT2_TIND_BLOCK #define EXT3_VALID_FS EXT2_VALID_FS #define EXT3_ERROR_FS EXT2_ERROR_FS #define EXT3_FT_REG_FILE EXT2_FT_REG_FILE #define EXT3_FT_CHRDEV EXT2_FT_CHRDEV #define EXT3_FT_BLKDEV EXT2_FT_BLKDEV #define EXT3_FT_FIFO EXT2_FT_FIFO #define EXT3_FT_SOCK EXT2_FT_SOCK #define EXT3_FT_SYMLINK EXT2_FT_SYMLINK #define EXT3_N_BLOCKS EXT2_N_BLOCKS #define EXT3_DIR_PAD EXT2_DIR_PAD #define EXT3_ROOT_INO EXT2_ROOT_INO #define EXT3_I_SIZE EXT2_I_SIZE #define EXT3_FEATURE_COMPAT_DIR_PREALLOC EXT2_FEATURE_COMPAT_DIR_PREALLOC #define EXT3_FEATURE_COMPAT_IMAGIC_INODES EXT2_FEATURE_COMPAT_IMAGIC_INODES #define EXT3_FEATURE_COMPAT_EXT_ATTR EXT2_FEATURE_COMPAT_EXT_ATTR #define EXT3_FEATURE_COMPAT_RESIZE_INODE EXT2_FEATURE_COMPAT_RESIZE_INODE #define EXT3_FEATURE_COMPAT_DIR_INDEX EXT2_FEATURE_COMPAT_DIR_INDEX #define EXT3_FEATURE_INCOMPAT_COMPRESSION EXT2_FEATURE_INCOMPAT_COMPRESSION #define EXT3_FEATURE_INCOMPAT_FILETYPE EXT2_FEATURE_INCOMPAT_FILETYPE #define EXT3_FEATURE_INCOMPAT_META_BG EXT2_FEATURE_INCOMPAT_META_BG #define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER #define EXT3_FEATURE_RO_COMPAT_LARGE_FILE EXT2_FEATURE_RO_COMPAT_LARGE_FILE #define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 typedef ext2_super_block ext3_super_block;typedef ext2_group_desc ext3_group_desc;typedef ext2_inode ext3_inode;typedef ext2_dir_entry_2 ext3_dir_entry_2;#include <ext2fs/ext2fs.h> #include "kernel-jbd.h" #ifndef USE_PCH #include <stdint.h> #endif extern uint32_t inode_count_;struct Inode : protected ext3_inode { public: __u16 mode (void ) const { return i_mode; } __u16 uid_low (void ) const { return i_uid_low; } off_t size (void ) const { return EXT3_I_SIZE(this); } __u32 atime (void ) const { return i_atime; } __u32 ctime (void ) const { return i_ctime; } __u32 mtime (void ) const { return i_mtime; } __u32 dtime (void ) const { return i_dtime; } __u16 gid_low (void ) const { return i_gid_low; } __u16 links_count (void ) const { return i_links_count; } __u32 blocks (void ) const { return i_blocks; } __u32 flags (void ) const { return i_flags; } __u32 const * block (void ) const { return i_block; } __u32 generation (void ) const { return i_generation; } __u32 file_acl (void ) const { return i_file_acl; } __u32 dir_acl (void ) const { return i_dir_acl; } __u32 faddr (void ) const { return i_faddr; } __u16 uid_high (void ) const { return i_uid_high; } __u16 gid_high (void ) const { return i_gid_high; } #ifndef i_reseved2 #define i_reserved2 osd2.hurd2.h_i_author #endif __u32 reserved2 (void ) const { return i_reserved2; } void set_reserved2 (__u32 val) { i_reserved2 = val; } bool is_orphan (void ) const { return i_links_count == 0 && i_atime && i_dtime < i_atime && i_dtime <= inode_count_; } bool has_valid_dtime (void ) const { return i_dtime && !is_orphan(); } bool is_deleted (void ) const { return i_links_count == 0 && i_mode && (i_block[0 ] == 0 || !((i_mode & 0xf000 ) == 0x4000 || (i_mode & 0xf000 ) == 0x8000 )); } };#endif
使用
在开始恢复前,选择一个目录来存放被恢复的文件.ext3grep 程序会在当前目录下创建一个名为 RESTORED_FILES 的目录来存放被恢复的文件.因此在运行 ext3grep 命令前,先要切换到一个你可读写的目录中.
因为进入了单用户模式,并且将根分区设成了只读,那么只能把恢复出来的文件放在U盘中了.因此,先 cd /mnt 进入U盘目录.如果你有幸记得你误删除的文件名及其路径的话,就可以直接用下面的命令进行恢复了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ext3grep /dev/your-device --restore-file path/to/your/file/filename ext3grep /dev/sda3 --restore-file /vi/tips.xml ext3grep /dev/sda3 --dump-names | tee filename.txt 上面的命令把 ext3grep 命令的输出记录到文件 filename.txt 中,你可以慢慢查看,或者使用 grep 命令过滤出你需要的信息. 当你知道了目录/文件的信息后,就可以用上面说的命令进行恢复了. ext3grep /dev/sda3 --restore-all
binlog
开启 Binlog,让 ext3grep 从 Binlog 中恢复,对数据库场景有用.
系统 密码重置 centos7 在启动菜单选择启动内核,按 e 编辑,找到 rhgb quiet 一行,把 rhgb quiet
替换为 init=/bin/bash
(临时生效) 按 CTRL+X
进入单用户模式 挂载根文件系统: mount -o remount,rw /
使用 passwd
命令直接设置 root 密码: passwd root
输入两次新密码. 最后,执行如下命令更新 SELinux: touch /.autorelabel
进入正常模式: exec /sbin/init
现在可以使用新设置的 root 密码登录了. Ubuntu14 方案一
重启电脑长按 shift 键直到进入进入 GRUB 引导模式,选择第二行 Ubuntu 高级选项, 选中直接回车 按 e 进入(recovery mode) 编译kernel进行启动参数 倒数第四行,删除 recovery nomodeset
,添加 quiet splash rw init=/bin/bash
。然后按 F10, 启动。 运行后系统直接进入 root mode,输入:passwd
方案二
重启电脑长按 shift 键直到进入进入 GRUB 引导模式,选择第二行 Ubuntu 高级选项, 选中直接回车 选择一个括号里是 recovery mode 的系统发行编号,回车进入 选择 root 项,回车 最下方输入 root 密码,回车,便会切换到 root 用户;此时需要输入此条命令 mount -o remount,rw /
回车,再用 passwd 用户名
便可以修改密码了; 继续输入 exit
返回,选中 resume
,回车,此时会跳出一个确认界面,再回车即可 会话 查 防 1 2 3 pkill -u linfengfeiye ps -ef| grep pts/0 kill -9 pid
修改账户超时值,设置自动注销时间 1 2 3 vim /etc/profile TMOUT =600
命令记录 进入 /home
各帐号目录下的 .bash_history
查看普通帐号的历史命令
history优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sed -i 's/^HISTSIZE=1000/HISTSIZE=10000/g' /etc/profile USER_IP=`who -u am i 2>/dev/null | awk '{print $NF}' | sed -e 's/[()]//g' `if [ "$USER_IP " = "" ]then USER_IP=`hostname`fi export HISTTIMEFORMAT="%F %T $USER_IP `whoami` " shopt -s histappendexport PROMPT_COMMAND="history -a" source /etc/profile
开机启动 查看开机启动服务 1 2 3 4 5 6 7 8 chkconfig chkconfig --list | grep "3:启用\|3:开\|3:on\|5:启用\|5:开\|5:on" ls /etc/init.d cat /etc/rc.local ls /etc/rc.d/rc[0~6].d runlevel
查看计划任务 1 2 3 4 5 6 7 8 9 10 11 12 crontab -l ls -alh /var/spool/cron ls -al /etc/ | grep cronls -al /etc/cron*cat /etc/cron*cat /etc/at.allowcat /etc/at.denycat /etc/cron.allowcat /etc/cron.denycat /etc/crontabcat /etc/anacrontabcat /var/spool/cron/crontabs/root
账号 异常查找 1 2 3 4 5 6 awk -F: '{if($3==0||$4==0)print $1}' /etc/passwd awk -F: '{if($7!="/usr/sbin/nologin"&&$7!="/sbin/nologin")print $1}' /etc/passwd awk '/\$1|\$6/{print $1}' /etc/shadow lastlog lastb users
异常设置 /etc/passwd
若用户 ID=0,则表示该用户拥有超级用户的权限 检查是否有多个 ID=0 禁用或删除多余的账号 /etc/login.defs
1 2 3 4 PASS_MAX_DAYS 90 PASS_MIN_DAYS 0 PASS_MIN_LEN 7 PASS_WARN_AGE 9
当查到异常用户时,需要立即禁用 1 2 3 usermod -L user userdel user userdel -r admin
安全配置 设置账户锁定登录失败锁定次数、锁定时间
1 2 3 4 vim /etc/pam.d/system-auth auth required pam_tally.so onerr=fail deny=6 unlock_time=300 auth required pam_tally.so deny=2 unlock_time=60 even_day_root root_unlock_time=60
安全审计 1 2 3 4 5 6 7 8 9 10 ps -ef | grep auditd more /etc/audit/audit.rules - w 文件 -p 权限(r读 w写 x执行 a修改文件属性) -k 关键字 - w /etc/passwd -p wa -k passwd_changes - a -系列动作 -S 系统调用名称 -F 字段-值 -k 关键字 - a exit ,always -S mount -S umount more /etc/audit/auditd.conf ausearch -i | less more /var/log/audit/audit.log
audit
linux audit 子系统是一个用于收集记录系统、内核、用户进程发生的行为事件的一种安全审计系统。该系统可以可靠地收集有关上任何与安全相关(或与安全无关)事件的信息,它可以帮助跟踪在系统上执行过的一些操作。
audit 和 syslog 有本质区别。syslog 记录的信息有限,主要目的是软件调试,对于用户的操作行为(如某用户修改删除了某文件)却无法通过这些日志文件来查看。而 audit 的目的则不同,它是 linux 安全体系的重要组成部分,是一种 “被动” 的防御体系。
1 2 3 4 5 yum install audit*.* -y service auditd start service auditd status
audit 安装后会生成 2 个配置文件:
/etc/audit/auditd.conf /etc/audit/audit.rules 具体配置信息请查看 文件
audit 常用命令
1 2 3 4 5 6 7 8 9 10 ausearch aureport auditctl -l aureport --user aureport --file aureport --summary auditctl -w /bin/rm -p x -k removefile
SELinux 关闭 SELinux
需要重启
1 2 3 vim /etc/selinux/config SELINUX=disabled
不需要重启
setenforce 0
进程 进程定位 1 2 3 4 5 6 7 ps -aux ps -ef service --status-all | grep running top pidof name pidof -x name lsof -g gid
进程限制 1 2 vim /etc/security/limits.conf user1 - nproc 20 # 退出后重新登录,就会发现最大进程数已经更改为 20 了
负载 文章
查询负载、进程监控
1 2 3 ps aux | grep Z ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head ps aux|head -1;ps aux|grep -v PID|sort -rn -k +4|head
清理缓存
1 2 3 4 5 sync echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches echo 3 > /proc/sys/vm/drop_caches sync
系统完整性 通过 rpm 自带的 -Va 来校验检查所有的 rpm 软件包,查看哪些命令是否被替换了
1 2 3 4 5 6 7 8 9 10 11 12 rpm -Va 验证内容中的8个信息的具体内容如下: - S 文件大小是否改变 - M 文件的类型或文件的权限(rwx)是否被改变 - 5 文件MD5校验是否改变(可以看成文件内容是否改变) - D 设备中,从代码是否改变 - L 文件路径是否改变 - U 文件的属主(所有者)是否改变 - G 文件的属组是否改变 - T 文件的修改时间是否改变
还原替换命令
1 2 3 4 rpm -qf /bin/ls mv /bin/ls /tmp rpm2cpio /mnt/cdrom/Packages/coreutils-8.4-19.el6.i686.rpm | cpio -idv ./bin/ls cp /root/bin/ls /bin/
日志 系统日志
对于日志文件的保护
1 2 3 chattr +a xxx chattr +a -R xxx
web日志
数据库日志
Net 端口 查
1 2 3 4 5 6 7 8 9 10 11 12 13 getent services lsof -i -P lsof -i:22 ss -tnlp ss -tnlp | grep ssh ss -tnlp | grep ":22" netstat -tnlp netstat -tnlp | grep ssh nmap -sV -p 22 localhost
更多内容查看 网络
防
Firewall 查
1 2 3 4 5 6 7 8 9 10 11 12 13 firewall-cmd --list-services firewall-cmd --state firewall-cmd --get-zones firewall-cmd --get-active-zones firewall-cmd --get-default-zone firewall-cmd --get-service firewall-cmd --get-service --permanent firewall-cmd --zone=public --list-ports firewall-cmd --zone=public --list-all cat /etc/hosts.deny cat /etc/hosts.allow
防
1 2 3 4 firewall-cmd --permanent --zone=public --remove-service=ssh firewall-cmd --permanent --zone=public --add-service=http firewall-cmd --permanent --zone=internal --add-source=1.1.1.1 firewall-cmd --reload
在上面的配置中,如果有人尝试从 1.1.1.1 去 ssh,这个请求将会成功,因为这个源区域(internal)被首先应用,并且它允许 ssh 访问.
如果有人尝试从其它的地址,如 2.2.2.2,去访问 ssh,它不是这个源区域的,因为和这个源区域不匹配.因此,这个请求被直接转到接口区域(public),它没有显式处理 ssh,因为,public 的目标是 default,这个请求被传递到默认动作,它将被拒绝.
如果 1.1.1.1 尝试进行 http 访问会怎样?源区域(internal)不允许它,但是,目标是 default,因此,请求将传递到接口区域(public),它被允许访问.
现在,让我们假设有人从 3.3.3.3 拖你的网站.要限制从那个 IP 的访问,简单地增加它到预定义的 drop 区域,正如其名,它将丢弃所有的连接:
1 2 firewall-cmd --permanent --zone=drop --add-source=3.3.3.3 firewall-cmd --reload
下一次 3.3.3.3 尝试去访问你的网站,firewalld 将转发请求到源区域(drop).因为目标是 DROP,请求将被拒绝,并且它不会被转发到接口区域(public).
注:配置了 firewalld 服务后一定要去检查下规则,因为他不会阻掉正在进行的连接,只能阻掉配置命令后进行的连接,所以你不知道你的ssh会话会不会一断就再也连不上了,血的教训🤣
iptable 查询表中的规则
1 2 3 4 iptables -t raw -L iptables -t mangle -L iptables -t nat -L iptables -t filter -L
查看不同的链中的规则
1 2 3 4 iptables -L INPUT iptables -vL INPUT iptables -nvL INPUT iptables --line-number -nvL INPUT
nftables 查看规则汇总
1 2 3 4 5 6 7 nft list tables [<family>] nft list table [<family>] <name> [-n] [-a] nft list tables nft list table family table nft list table inet filter nft list chain family table chain nft list chain inet filter output
nft表管理
1 2 3 4 5 6 nft add table family table nft list tables nft list table family table nft list table inet filter nft delete table family table nft flush table family table
nft链管理
1 2 3 4 5 6 7 8 9 nft add chain family table chain nft add chain inet filter tcpchain nft add chain family table chain { type type hook hook priority priority \; } nft list chain family table chain nft list chain inet filter output nft chain family table chain { [ type type hook hook device device priority priority \; policy <policy> \; ] } nft chain inet filter input { policy drop \; } nft delete chain family table chain nft flush chain family table chain
添加规则
1 2 nft add rule family table chain handle handle statement nft insert rule family table chain handle handle statement
删除规则
1 2 3 4 5 6 7 8 9 nft --handle --numeric list chain inet filter input nft delete rule inet fltrTable input handle 10 nft flush table foo nft flush chain foo bar nft delete rule ip6 foo bar
自动重载
1 2 3 4 5 6 7 8 9 清空当前规则集: 导出当前规则集: 可以直接修改/tmp/nftables文件,使更改生效则运行:
禁ping 临时性,重启后失效
1 2 echo 0 >/proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all
长期性
1 2 3 vim /etc/rc.d/rc.localecho 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
或
1 2 3 vim /etc/sysctl.conf net.ipv4.icmp_echo_ignore_all=1
sysctl -p
使新配置生效
SSH 文章
查
查询可以远程登录的帐号信息
1 awk '/\$1|\$6/{print $1}' /etc/shadow
查看尝试暴力破解机器密码的人
1 2 3 4 5 grep "Failed password for root" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more
查看暴力猜用户名的人
1 2 3 4 5 6 7 grep "Failed password for invalid user" /var/log/auth.log | awk '{print $13}' | sort | uniq -c | sort -nr | more grep "Failed password for invalid user" /var/log/secure | awk '{print $13}' | sort | uniq -c | sort -nr | more grep "Failed password" /var/log/secure | awk {'print $9' } | sort | uniq -c | sort -nr grep -o "Failed password" /var/log/secure|uniq -c
IP 信息
1 2 3 4 5 grep "Failed password for root" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more grep "Failed password for root" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr | more
登录成功
1 2 3 4 5 6 7 grep "Accepted " /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more grep 'Accepted' /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr grep "Accepted " /var/log/secure | awk '{print $1,$2,$3,$9,$11}' grep "Accepted " /var/log/secure* | awk '{print $1,$2,$3,$9,$11}'
私钥
1 2 ll -al /etc/ssh/ ll -al /root/.ssh/
防
ping 钥匙
1 2 3 4 5 6 7 8 9 10 11 12 13 14 iptables -A INPUT -p icmp -m icmp --icmp-type 8 -m length --length 1078 -m recent --name sshKeyList --set -j ACCEPT iptables -A INPUT -p tcp -m tcp --dport 22 --syn -m recent --name sshKeyList --rcheck --seconds 30 --hitcount 6 -j DROP iptables -A INPUT -p tcp -m tcp --dport 22 --syn -m recent --name sshKeyList --rcheck --seconds 30 --hitcount 5 -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT iptables -A INPUT -j DROP
更改默认端口
修改 /etc/ssh/sshd_config
文件,将其中的 Port 22 改为指定的端口
!!! 警告,记得防火墙要先放行端口,不然你的远程主机就连不上了🤣!!!
配置使用 RSA 私钥登录
先生成你的客户端的密钥,包括一个私钥和公钥
把公钥拷贝到服务器上,注意,生成私钥的时候,文件名是可以自定义的,且可以再加一层密码,所以建议文件名取自己能识别出哪台机器的名字.
然后在服务器上,你的用户目录下,新建 .ssh
文件夹,并将该文件夹的权限设为 700
1 2 3 cd mkdir .sshchmod 700 .ssh
新建一个 authorized_keys,这是默认允许的 key 存储的文件.如果已经存在,则只需要将上传的 id_rsa.pub 文件内容追加进去即可,如果不存在则新建并改权限为 400 即可. 然后编辑 ssh 的配置文件
1 2 3 4 mv id_rsa.pub .sshcd .sshcat id_rsa.pub >> authorized_keyschmod 600 authorized_keys
1 2 3 4 5 6 vim /etc/ssh/sshd_config RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile /root/.ssh/authorized_keys PasswordAuthentication no
service sshd restart
重启 sshd 服务
测试使用私钥登录
禁止 root 用户登录
可以建一个用户来专门管理,而非直接使用 root 用户,修改 /etc/ssh/sshd_config
1 2 3 vim /etc/ssh/sshd_config PermitRootLogin no
使用 Fail2ban
SSH 陷阱
文件共享 NFS服务
配置文件
TFTP服务
配置文件
1 2 3 /etc/ default /tftpd-hpa/etc/ xinetd.d/tftp
samba服务
配置文件
加固 查后门 相关文章
添加 root 权限后门用户
检查 /etc/passwd
文件是否有异常
vim 后门
检测对应 vim 进程号虚拟目录的 map 文件是否有 python 字眼.
查看连接情况 netstat -antlp
例如发现 vim pid 为 12
1 2 3 file /proc /12/exemore /proc /12/cmdlinemore /proc /12/maps | grep python
strace 记录
通过排查 shell 的配置文件或者 alias
命令即可发现,例如 ~/.bashrc
和 ~/.bash_profile
文件查看是否有恶意的 alias 问题.
定时任务和开机启动项
一般通过 crontab -l
命令即可检测到定时任务后门.不同的 linux 发行版可能查看开机启动项的文件不大相同,Debian 系 linux 系统一般是通过查看 /etc/init.d
目录有无最近修改和异常的开机启动项.而 Redhat 系的 linux 系统一般是查看 /etc/rc.d/init.d
或者 /etc/systemd/system
等目录.
预加载型动态链接库后门 ld.so.preload
通过 strace
命令去跟踪预加载的文件是否为 /etc/ld.so.preload
,以及文件中是否有异常的动态链接库.以及检查是否设置 LD_PRELOAD 环境变量等.注意:在进行应急响应的时候有可能系统命令被替换或者关键系统函数被劫持(例如通过预加载型动态链接库后门),导致系统命令执行不正常,这个时候可以下载 busybox.下载编译好的对应平台版本的 busybox,或者下载源码进行编译通过U盘拷贝到系统上,因为 busybox 是静态编译的,不依赖于系统的动态链接库,busybox 的使用类似如下 busybox ls,busybox ps -a.
内核级 rootkit
可以通过 unhide 等工具进行排查,更多内容见 应急
深信服 Web 后门扫描
http://edr.sangfor.com.cn/backdoor_detection.html
杀毒 ClamavNet
配置 pam.d 策略