| 知乎专栏 |
在国内工作交接如同家常便饭,有数据显示员工服务于公司的平均时间,其中80后平均是3年时间,90后平均为2~2.5,95后约半年~1.5年。如此频繁地更换工作不仅仅是员工自身问题,公司用人单位也存在一定问题,这里就不讨论了。
在早期管理学还未在中国普及的时候,50/60/70后沿用了自古以来的老旧的管理思想,搞仁制和驭人术那套,如今已经是2022年了,管理学已经非常成熟,大学有专门管理课,社会上有专业的管理培训,但仍有大量公司在采用中式管理,且管理层搞得不亦乐乎,并未有改变的想法。
国内公司存在的问题:
所以在工作中,工作交接是不可避免的,无论是用人单位找到你,还是你主动应聘岗位,工作交接都是一项极具挑战的工作,俗称“擦屁股”,我们怎样做好工作交接呢?
任何工作交接都会丢失80%内容,交接者只能接受20%的工作内容。
丢失的内容有可能是交接者没有想到,交接者故意隐瞒,交接者故意挖坑,交接者说了但是接受者没听懂或忘记了,总之工作不可能达到 100% 的交接。
尤其是国内企业和雇员紧张的劳动关系,几乎大部分的工作交接都不太顺利。
同时离职员工去下家公司也同样面临严峻挑战的工作交接过程,似乎这是一个无解的死循环。
即使是我们口中常说的大厂也存在上述问题。
工作交接过程中可能遇到的问题:
你能做的是尽量获得更多交接文档,很多事你要先想到,主动问对方,交接者没有责任和义务帮你,他想尽快甩锅走人,你只能求菩萨保佑他跟用人单位没有纠纷。
这导致很多时候工作交接要靠我们自己,同时我们离职的时候也会用这些办法对付接收我们工作的人,呵呵!!!
以技术工作交接为例,如何快速摸清系统,掌握各系统模块之间的关系呢?
互联网入口都有哪些:
使用 nslookup/dig 等工具检查域名
然后在登陆的DNS管理界面查漏补缺,这里重点是 MX 记录,很多时候会忽略,导致邮件服务不能用。
登陆网络设备,备份配置文件,然后分析网络拓扑,如果有交接文档,就按照文档核对 vlan和每个路由器和交换机端口功能。
Cisco 网络设备使用 show running-config 查看配置文件
Router#show running-config Router#show startup-config
H3C 网络设备使用 display current-configuration 查看配置文件
[WA2220E-AG]display current-configuration # version 5.20, Release 1110P01 # sysname WA2220E-AG # domain default enable system # telnet server enable # port-security enable # vlan 1 # radius scheme system # domain system access-limit disable state active idle-cut disable self-service-url disable
Juniper 网络设备,使用 get config 查看配置文件
[root@netkiller ~]# ssh neo@192.168.1.1 neo@192.168.3.1's password: Remote Management Console firewall-> get config Total Config size 17376: set clock ntp set clock timezone 7 set vrouter trust-vr sharable set vrouter "untrust-vr" exit set vrouter "trust-vr" unset auto-route-export exit ... ... ... exit set vrouter "untrust-vr" exit set vrouter "trust-vr" exit firewall->
这些网络设备如何使用,请参考《Netkiller Network 手札》
几乎90%(可以我说少了)公司,在IT这块的管理十分混乱,走进机房,网线乱如麻,你根本不知道那根网线链接了什么设备,我们需要先理清重点设备的链接拓扑图。
这里以 H3C 为例,其他设备操作方式大同小异,下面是找到接口对等设备的IP地址
<H3C>display arp interface GE1/0/32 Type: S-Static D-Dynamic O-Openflow R-Rule M-Multiport I-Invalid IP address MAC address VLAN/VSI name Interface Aging Type 172.16.200.75 b07b-2523-5326 200 GE1/0/32 501 D
通过 mac 地址找接口
<H3C>display arp all | include 6227-d242-269e 172.16.0.68 6227-d242-269e 10 GE1/0/3 1085 D
通过 ip 地址找接口
<H3C>display arp all | include 172.16.200.102 172.16.200.102 001e-67fa-df92 200 GE1/0/36 282 D
当我们知道服务器IP地址之后就可以登录服务器了
[root@netkiller ~]# ssh root@www.netkiller.cn
登陆服务器之后首先快速检查是否有安全问题
[root@netkiller ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin systemd-coredump:x:999:997:systemd Core Dumper:/:/sbin/nologin systemd-resolve:x:193:193:systemd Resolver:/:/sbin/nologin tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin polkitd:x:998:996:User for polkitd:/:/sbin/nologin unbound:x:997:993:Unbound DNS resolver:/etc/unbound:/sbin/nologin libstoragemgmt:x:996:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin setroubleshoot:x:995:991::/var/lib/setroubleshoot:/sbin/nologin cockpit-ws:x:994:990:User for cockpit web service:/nonexisting:/sbin/nologin cockpit-wsinstance:x:993:989:User for cockpit-ws instances:/nonexisting:/sbin/nologin sssd:x:992:988:User for sssd:/:/sbin/nologin chrony:x:991:987::/var/lib/chrony:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin nscd:x:28:28:NSCD Daemon:/:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin docker:x:986:986:Container Administrator:/home/docker:/bin/bash git:x:1000:1000::/home/git:/bin/bash caddy:x:985:984:Caddy web server:/var/lib/caddy:/sbin/nologin nginx:x:984:983:Nginx web server:/var/lib/nginx:/sbin/nologin
通常除了 root 用户,小于1000的UID的用户 SHELL 应该是 /sbin/nologin
重点检查拥有 shell 权限的用户,非必要全部改为 /sbin/nologin
[root@netkiller ~]# cat /etc/passwd | grep bash root:x:0:0:root:/root:/bin/bash docker:x:986:986:Container Administrator:/home/docker:/bin/bash git:x:1000:1000::/home/git:/bin/bash
检查用户是否激活,并设置密码
[root@netkiller ~]# cat /etc/shadow root:$6$XyW4o/lZWdu$VsjNYW8nVcE63cWwAxLxBe5s22vt4hQCOivzxo5RQ3rGbcBkfWnc/ATiy073D7/aIHQaDZplIJWz51s4Pzkn0.:19173:0:99999:7::: bin:*:18505:0:99999:7::: daemon:*:18505:0:99999:7::: adm:*:18505:0:99999:7::: lp:*:18505:0:99999:7::: sync:*:18505:0:99999:7::: shutdown:*:18505:0:99999:7::: halt:*:18505:0:99999:7::: mail:*:18505:0:99999:7::: operator:*:18505:0:99999:7::: games:*:18505:0:99999:7::: ftp:*:18505:0:99999:7::: nobody:*:18505:0:99999:7::: dbus:!!:19136:::::: systemd-coredump:!!:19136:::::: systemd-resolve:!!:19136:::::: tss:!!:19136:::::: polkitd:!!:19136:::::: unbound:!!:19136:::::: libstoragemgmt:!!:19136:::::: setroubleshoot:!!:19136:::::: cockpit-ws:!!:19136:::::: cockpit-wsinstance:!!:19136:::::: sssd:!!:19136:::::: chrony:!!:19136:::::: sshd:!!:19136:::::: tcpdump:!!:19136:::::: nscd:!!:19136:::::: postfix:!!:19136:::::: docker:$6$6.KJvlfezlr7q09N$Xo83rIqChY0sLrvyCGnNYqPpCsREk1h1En7eNwZBV9sjN6XVOO9xgjuKGn..tAhElYK1SLI6mvZa6pxsCcuqb/:19177:0:99999:7::: git:$6$EcduJ7Z1HAZWhRPN$wyG7OOpQaw84FgvAsXBPUKr.dZWEDIaWhMKeoEuNRvpfzvoeKo4gei028lSCm./nAvFqRpos/2Ng4ARHR5FRj.:19173:0:99999:7::: caddy:!!:19177:::::: nginx:!!:19192::::::
!! 和 * 是未设置密码,该用户无法登陆系统,$6$ 表示该用户有密码
这三个用户是有密码的
[root@netkiller ~]# cat /etc/shadow | grep '\$6\$' root:$6$XyW4o/lZWdu$VsjNYW8nVcE63cWwAxLxBe5s22vt4hQCOivzxo5RQ3rGbcBkfWnc/ATiy073D7/aIHQaDZplIJWz51s4Pzkn0.:19173:0:99999:7::: docker:$6$6.KJvlfezlr7q09N$Xo83rIqChY0sLrvyCGnNYqPpCsREk1h1En7eNwZBV9sjN6XVOO9xgjuKGn..tAhElYK1SLI6mvZa6pxsCcuqb/:19177:0:99999:7::: git:$6$EcduJ7Z1HAZWhRPN$wyG7OOpQaw84FgvAsXBPUKr.dZWEDIaWhMKeoEuNRvpfzvoeKo4gei028lSCm./nAvFqRpos/2Ng4ARHR5FRj.:19173:0:99999:7:::
发现可疑用户,我们可以先把它锁掉,让他登陆不了。使用 passwd -l 给用户加锁,-u 解锁。
[root@netkiller ~]# passwd --help
Usage: passwd [OPTION...] <accountName>
-k, --keep-tokens keep non-expired authentication tokens
-d, --delete delete the password for the named account (root only); also removes password lock if any
-l, --lock lock the password for the named account (root only)
-u, --unlock unlock the password for the named account (root only)
-e, --expire expire the password for the named account (root only)
-f, --force force operation
-x, --maximum=DAYS maximum password lifetime (root only)
-n, --minimum=DAYS minimum password lifetime (root only)
-w, --warning=DAYS number of days warning users receives before password expiration (root only)
-i, --inactive=DAYS number of days after password expiration when an account becomes disabled (root only)
-S, --status report password status on the named account (root only)
--stdin read new tokens from stdin (root only)
Help options:
-?, --help Show this help message
--usage Display brief usage message
例如我们要禁止 git 用户登陆系统
[root@netkiller ~]# passwd -l git Locking password for user git. passwd: Success
恢复 git 用户登陆权限
[root@netkiller ~]# passwd -u git Unlocking password for user git. passwd: Success
实际的加锁与解锁的过程就是在 shadow 文件中,密码前面增加 !! 符号。
[root@netkiller ~]# passwd -l git Locking password for user git. passwd: Success [root@netkiller ~]# cat /etc/shadow | grep 'git' git:!!$6$EcduJ7Z1HAZWhRPN$wyG7OOpQaw84FgvAsXBPUKr.dZWEDIaWhMKeoEuNRvpfzvoeKo4gei028lSCm./nAvFqRpos/2Ng4ARHR5FRj.:19173:0:99999:7::: [root@netkiller ~]# passwd -u git Unlocking password for user git. passwd: Success [root@netkiller ~]# cat /etc/shadow | grep 'git' git:$6$EcduJ7Z1HAZWhRPN$wyG7OOpQaw84FgvAsXBPUKr.dZWEDIaWhMKeoEuNRvpfzvoeKo4gei028lSCm./nAvFqRpos/2Ng4ARHR5FRj.:19173:0:99999:7:::
非法进入服务器必须某种服务端口,我们确认用户安全后,接下来要做的就是扫描端口,看看服务器上开了哪些端口。
[root@netkiller ~]# dnf install -y nmap
nmap 使用方法请看我的《Netkiller Linux 手札》本文只教方法论。
[root@netkiller ~]# nmap www.netkiller.cn Starting Nmap 7.70 ( https://nmap.org ) at 2022-07-23 16:23 CST Nmap scan report for chat.netkiller.cn (8.219.73.35) Host is up (0.00041s latency). Not shown: 993 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 3389/tcp closed ms-wbt-server 8000/tcp closed http-alt 8080/tcp closed http-proxy 9000/tcp closed cslistener Nmap done: 1 IP address (1 host up) scanned in 25.40 seconds
通过端口找进程,可以使用 ss 和 netstat 两个工具完成
[root@netkiller ~]# netstat -antup|grep 80
tcp 0 0 172.22.119.108:20507 100.103.15.60:80 ESTABLISHED 1490/AliYunDun
tcp6 0 0 :::80 :::* LISTEN 1629762/caddy
[root@netkiller ~]# ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1189,fd=5))
LISTEN 0 1024 127.0.0.1:2019 0.0.0.0:* users:(("caddy",pid=1629762,fd=3))
LISTEN 0 1024 *:80 *:* users:(("caddy",pid=1629762,fd=8))
LISTEN 0 1024 *:443 *:* users:(("caddy",pid=1629762,fd=7))
这里可以看到 80 端口是 1629762 进程监听的,该进程是 caddy 它是一个 web 服务器
通过进程找进程ID
[root@netkiller ~]# pgrep caddy 1629762
多IP地址骚猫
while read ipaddress
do
echo "----- $ipaddress ----- "
nmap -p 1-65535 $ipaddress | tail -n +5 | head -n -1
echo
done << EOF
172.16.0.1
172.18.0.1
192.168.0.1
EOF
Linux 系统进程带有中括号的是内核进程,除此之外都需要一一排查
[root@netkiller ~]# ps ax | grep '\['
2 ? S 0:01 [kthreadd]
3 ? I< 0:00 [rcu_gp]
4 ? I< 0:00 [rcu_par_gp]
6 ? I< 0:00 [kworker/0:0H-events_highpri]
9 ? I< 0:00 [mm_percpu_wq]
10 ? S 0:00 [rcu_tasks_rude_]
11 ? S 0:00 [rcu_tasks_trace]
12 ? S 0:01 [ksoftirqd/0]
13 ? I 9:14 [rcu_sched]
14 ? S 0:00 [migration/0]
15 ? S 0:00 [watchdog/0]
16 ? S 0:00 [cpuhp/0]
17 ? S 0:00 [cpuhp/1]
18 ? S 0:00 [watchdog/1]
19 ? S 0:00 [migration/1]
20 ? S 0:00 [ksoftirqd/1]
22 ? I< 0:00 [kworker/1:0H-events_highpri]
23 ? S 0:00 [cpuhp/2]
24 ? S 0:01 [watchdog/2]
25 ? S 0:00 [migration/2]
26 ? S 0:00 [ksoftirqd/2]
28 ? I< 0:00 [kworker/2:0H-events_highpri]
29 ? S 0:00 [cpuhp/3]
30 ? S 0:01 [watchdog/3]
31 ? S 0:00 [migration/3]
32 ? S 0:00 [ksoftirqd/3]
34 ? I< 0:00 [kworker/3:0H-events_highpri]
35 ? S 0:00 [cpuhp/4]
36 ? S 0:01 [watchdog/4]
37 ? S 0:00 [migration/4]
38 ? S 0:00 [ksoftirqd/4]
40 ? I< 0:00 [kworker/4:0H-events_highpri]
41 ? S 0:00 [cpuhp/5]
42 ? S 0:01 [watchdog/5]
43 ? S 0:00 [migration/5]
44 ? S 0:00 [ksoftirqd/5]
46 ? I< 0:00 [kworker/5:0H-events_highpri]
47 ? S 0:00 [cpuhp/6]
48 ? S 0:01 [watchdog/6]
49 ? S 0:00 [migration/6]
50 ? S 0:00 [ksoftirqd/6]
52 ? I< 0:00 [kworker/6:0H-events_highpri]
53 ? S 0:00 [cpuhp/7]
54 ? S 0:02 [watchdog/7]
55 ? S 0:00 [migration/7]
56 ? S 0:00 [ksoftirqd/7]
58 ? I< 0:00 [kworker/7:0H-events_highpri]
67 ? S 0:00 [kdevtmpfs]
68 ? I< 0:00 [netns]
69 ? S 0:00 [kauditd]
70 ? S 0:01 [khungtaskd]
71 ? S 0:00 [oom_reaper]
72 ? I< 0:00 [writeback]
73 ? S 0:00 [kcompactd0]
74 ? SN 0:00 [ksmd]
75 ? SN 0:18 [khugepaged]
76 ? I< 0:00 [crypto]
77 ? I< 0:00 [kintegrityd]
78 ? I< 0:00 [kblockd]
79 ? I< 0:00 [blkcg_punt_bio]
80 ? I< 0:00 [tpm_dev_wq]
81 ? I< 0:00 [md]
82 ? I< 0:00 [edac-poller]
83 ? S 0:00 [watchdogd]
84 ? I< 0:01 [kworker/0:1H-kblockd]
118 ? S 0:00 [kswapd0]
224 ? I< 0:00 [kthrotld]
225 ? I< 0:00 [acpi_thermal_pm]
226 ? I< 0:00 [kmpath_rdacd]
227 ? I< 0:00 [kaluad]
229 ? I< 0:02 [kworker/4:1H-kblockd]
230 ? I< 0:00 [ipv6_addrconf]
232 ? I< 0:00 [kstrp]
313 ? I< 0:01 [kworker/5:1H-kblockd]
319 ? I< 0:01 [kworker/2:1H-kblockd]
347 ? I< 0:14 [kworker/7:1H-xfs-log/vda1]
350 ? I< 0:01 [kworker/3:1H-kblockd]
355 ? I< 0:01 [kworker/1:1H-kblockd]
361 ? I< 0:01 [kworker/6:1H-kblockd]
501 ? I< 0:00 [ata_sff]
502 ? S 0:00 [scsi_eh_0]
503 ? I< 0:00 [scsi_tmf_0]
504 ? S 0:00 [scsi_eh_1]
505 ? I< 0:00 [scsi_tmf_1]
533 ? I< 0:00 [xfsalloc]
535 ? I< 0:00 [xfs_mru_cache]
536 ? I< 0:00 [xfs-buf/vda1]
537 ? I< 0:00 [xfs-conv/vda1]
538 ? I< 0:00 [xfs-cil/vda1]
539 ? I< 0:00 [xfs-reclaim/vda]
540 ? I< 0:00 [xfs-blockgc/vda]
542 ? I< 0:00 [xfs-log/vda1]
543 ? S 2:57 [xfsaild/vda1]
880 ? I< 0:00 [nfit]
1636473 ? I 0:01 [kworker/5:2-events_power_efficient]
1636635 ? I 0:07 [kworker/7:0-events]
1636884 ? I 0:00 [kworker/6:0-events]
1636886 ? I 0:00 [kworker/2:3-events]
1637134 ? I 0:00 [kworker/1:0-events]
1637224 ? I 0:00 [kworker/2:0]
1637273 ? I 0:00 [kworker/0:3-mm_percpu_wq]
1637275 ? I 0:00 [kworker/u16:0-events_unbound]
1637290 ? I 0:00 [kworker/6:2-mm_percpu_wq]
1637344 ? I 0:00 [kworker/1:1]
1637352 ? Ss 0:00 sshd: root [priv]
1637362 ? I 0:00 [kworker/0:2-events]
1637501 ? I 0:00 [kworker/4:1-events]
1637953 ? I 0:00 [kworker/3:0-cgroup_pidlist_destroy]
1637956 ? I< 0:00 [ib-comp-wq]
1637957 ? I< 0:00 [kworker/u17:0]
1637958 ? I< 0:00 [ib-comp-unb-wq]
1637960 ? I< 0:00 [ib_mcast]
1637961 ? I< 0:00 [ib_nl_sa_wq]
1637965 ? I 0:00 [kworker/5:0]
1637976 ? I 0:00 [kworker/4:0-xfs-sync/vda1]
1637979 ? I 0:00 [kworker/7:2]
1637981 ? I 0:00 [kworker/3:3-cgroup_destroy]
1637986 ? I 0:00 [kworker/u16:1-events_unbound]
1638007 pts/0 S+ 0:00 grep --color=auto \[
使用 grep -v 排除所有内核进程,这样看着舒服一些。
[root@netkiller ~]# ps ax | grep -v '\['
PID TTY STAT TIME COMMAND
1 ? Ss 3:08 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
649 ? Ss 0:21 /usr/lib/systemd/systemd-journald
681 ? Ss 0:02 /usr/lib/systemd/systemd-udevd
711 ? S<sl 0:04 /sbin/auditd
716 ? S< 0:01 /usr/sbin/sedispatch
759 ? Ss 0:03 /usr/bin/lsmd -d
769 ? Ss 0:00 /usr/sbin/smartd -n -q never
770 ? Ssl 0:01 /usr/lib/polkit-1/polkitd --no-debug
779 ? Ss 0:14 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
788 ? Ss 0:00 /usr/sbin/mcelog --ignorenodev --daemon --foreground
794 ? S 0:08 /usr/sbin/chronyd
974 ? Ss 0:08 /usr/lib/systemd/systemd-logind
1023 ? Ssl 1:03 /usr/sbin/NetworkManager --no-daemon
1027 ? Ssl 76:19 /usr/libexec/platform-python -Es /usr/sbin/tuned -l -P
1189 ? Ss 0:01 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512 -oGSSAPIKexAlgorithms=gss-curve25519-sha256-,gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gss-group14-sha1- -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 -oHostKeyAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oPubkeyAcceptedKeyTypes=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oCASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa
1201 ? Ss 0:00 /usr/sbin/atd -f
1233 tty1 Ss+ 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
1234 ttyS0 Ss+ 0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
1461 ? S<sl 22:04 /usr/local/aegis/aegis_update/AliYunDunUpdate
1490 ? S<sl 412:12 /usr/local/aegis/aegis_client/aegis_11_25/AliYunDun
1652 ? Ss 0:02 /usr/sbin/crond -n
1702 ? Ssl 1:25 /usr/sbin/rsyslogd -n
4186 ? Ssl 35:58 /usr/bin/containerd
4200 ? Ssl 26:56 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
221773 ? Ss 0:01 /usr/sbin/sssd -i --logger=files
221775 ? S 0:09 /usr/libexec/sssd/sssd_be --domain implicit_files --uid 0 --gid 0 --logger=files
221776 ? S 3:32 /usr/libexec/sssd/sssd_nss --uid 0 --gid 0 --logger=files
298641 ? Ssl 31:55 /usr/local/share/aliyun-assist/2.2.3.309/aliyun-service
298799 ? Ssl 5:34 /usr/local/share/assist-daemon/assist_daemon
1629762 ? Ssl 0:23 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
1637356 ? Ss 0:00 /usr/lib/systemd/systemd --user
1637358 ? S 0:00 (sd-pam)
1637366 ? S 0:00 sshd: root@pts/0
1637367 pts/0 Ss 0:00 -bash
1638004 pts/0 R+ 0:00 ps ax
对于可疑进程一律找到它所在位置,先kill掉,然后去掉可执行权限,归档备份。
例如我们对 caddy 下手,首先查看进程位置 /usr/bin/caddy
[root@netkiller ~]# ps ax |grep caddy 1629762 ? Ssl 0:23 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile 1637983 pts/0 S+ 0:00 grep --color=auto caddy
看看是否有系统启动服务
systemctl stop caddy systemctl disable caddy
现在就禁用了,如果这个程序是手工安装没有systemd,我们就需要 chmod -x /usr/bin/caddy
以上是 caddy 为例,其他服务也都如此。
目前许多公司都在使用 Docker / Kubernetes 部署系统,其实容器并非安全,在容器镜像中藏点私货是非常容易的,Docker 官方提供了安全扫描工具
[root@netkiller ~]# docker scan Docker Scan relies upon access to Snyk, a third party provider, do you consent to proceed using Snyk? (y/N)
我们安装物理机所用的系统通常是去官网下载,很多容器的制作并为使用官方镜像,同时会做 md5sum 校验,所以是安全的。容器镜像安全更多是来自无序的继承,经过多次继承我们不知道里面做了那些变化,所以选择基础镜像非常重要。
[root@netkiller ~]# cat Dockerfile | grep FROM FROM nginx:latest
如果不是官方镜像,需要格外注意
云平台通常网络分成WLAN和LAN两个部分,有些平台WLAN 是挂载到 eth0 上,有些平台云主机只有内网IP,WLAN是映射到内网IP上。
采用的手段跟上面一样,扫描端口,检查安全组规则,弹性IP和SLB策略。
原则是,WLAN外网只允许通过特定端口例如80/443,剩下所有服务在LAN上通信。
工作交接期间,只开放80/443端口,完成交接后,并做了安全排查之后,逐渐开放需要的端口,建议限制来源IP地址,例如只允许从办公室访问。
这个步骤是搞清楚代码从开发到生产环境是怎么部署的,如果使用了CI/CD技术,就从持续集成和部署着手看,可以一目了然。如果是手工部署,要亲力亲为自己做一遍,同时将CI/CD就此机会做起来。
举一个例子,比如有一个项目教 api.netkiller.cn
代码库中找到这个项目
目前国内最主流搭配是前端 node 后端 java,当然也有少量项目使用 PHP、Python和Go,总体大同小异。
如果是 node.js 项目通常是 webpack 无非就是下面两步
npm install --registry=https://registry.npm.taobao.org npm run build:prod
Java 项目
mvn clean package
前端 NodeJS 项目配置通常只链接后端,配置涉及较少,相对容易掌握。
Java 项目配置文件放在 src/main/resources/ 中 Springboot 项目配置文件是 src/main/resources/application.yml,Springcloud 的配置文件是 src/main/resources/bootstrap.yml
也有使用 application.properties 和 bootstrap.properties
我们既要检查配置文件中都链接了那些服务,还要检查配置是否合理,例如链接池的最大链接数量,链接超时时间等等。
如果使用配置中心,需要进入配置中心查看配置文件
走一遍业务逻辑,从域名进入网站到数据保存到数据,这中间经过了那些服务,他们的调用关系是什么,画一张图,让你一清二楚。
如果有链路追踪能让你更快完成这步工作,如果没有,这也是未来要做的工作,这时就需要结合各种配置文件,或者询问各种相关部门和人员来完成这个拓扑图。
程序猿常常自嘲是粪海狂蛆!陈年的粪缸,经过发酵、沉淀、分解已经没有屎尿的味道,你千万别去动它。
国内大部分项目都是平均三年经验的开发人写的,同时90后平均不到两年就会换工作,你别期望代码质量有多高,你别更别期望问同事能得到答案。
常态是,大部分情况下,只要修改代码就产生新bug!延伸阅读《程序猿说的「优化」是什么意思?》
代码审查只是一句口号历来如此,很多团队都说在做,实际情况你懂的。但是此时一些对外的服务真的有必要做一次 code review,我的职业生涯中,曾经遇到过离职人员埋后门的情况。
经过前面的服务器排查,通过SSH登陆服务器搞破坏的可能性是极小的,更多的漏洞是代码漏洞和业务漏洞。
使用代码扫描工具,例如 SonarQube 扫描lib和引用第三方包的安全漏洞,及时升级第三方包,修复存在安全的代码。
如果你期待代码扫描能帮你找出业务漏洞,纯属扯淡,我们使用代码扫描更多是发现 pom.xml 中引用第三方库已知的 CVE 漏洞。