# 通过 systemctl 管理服务

基本那个,systemd 启动服务的机制,主要是通过 systemctl 指令来处理。

而以前的 systemV 需要 service、chkconfig、setup、init 等指令来完成。

# 管理单一服务 service unit 的启动、开机启动与观察状态

systemctl [command] [unit]

commond 主要有:
	start: 立刻启动后面的 unit
	stop:立刻关闭后面的 unit
	restart:立刻关闭后启动后面的 unit
	reload:不关闭后面的 unit 的情况下,重载配置文件,让设置生效
	enable:设置开机启动
	disable:取消开机启动
	status:列出 unit 有没有正在执行、开机预设执行、登录等信息
	is-active:目前是否在运行
	is-enable:是否开机启动
1
2
3
4
5
6
7
8
9
10
11
12
# 范例 1:看看目前 atd 这个服务的状态
[root@study ~]# systemctl status atd.service 
* atd.service - Job spooling tools
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-03-17 10:49:55 CST; 1 day 5h ago
 Main PID: 1398 (atd)
    Tasks: 1
   CGroup: /system.slice/atd.service
           `-1398 /usr/sbin/atd -f

Mar 17 10:49:55 study.centos.mrcode systemd[1]: Started Job spooling tools.
# 重点在第 2、3 行数据
# Loaded:开机是否启动
# Active:是否正在运行中
# 最后一行:该服务的启动信息
# 登录文件格式为:时间、信息发送主机、哪一个服务的信息、实际信息内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 范例 2:正常关闭 atd 服务,非 kill -9
[root@study ~]# systemctl stop atd.service 
[root@study ~]# systemctl status atd.service 
* atd.service - Job spooling tools
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2020-03-18 16:40:06 CST; 13s ago
  Process: 1398 ExecStart=/usr/sbin/atd -f $OPTS (code=exited, status=0/SUCCESS)
 Main PID: 1398 (code=exited, status=0/SUCCESS)

Mar 17 10:49:55 study.centos.mrcode systemd[1]: Started Job spooling tools.
Mar 18 16:40:06 study.centos.mrcode systemd[1]: Stopping Job spooling tools...
Mar 18 16:40:06 study.centos.mrcode systemd[1]: Stopped Job spooling tools.
# 这下就明白了。后面两行信息是执行 stop 后发生的事件日志信息
1
2
3
4
5
6
7
8
9
10
11
12
13

不要使用 kill 的方式来关掉一个正常的服务,否则 systemctl 无法监控该服务。上面信息的 Active 状态有如下几个常见的状态:

  • active(running):有一个或多个程序正在运行

  • active(exited):仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行。

    比如:开机或是挂载时才会进行一次的 quotaon 功能,就是这种模式,quotaon 不需要一直执行,只需要执行一次之后,就交给文件系统自行处理了。通常用 bash shell 写的小型服务,大多属于此种类型(无需常驻内存)

  • active(waiting):正在执行中中,不过在在等待其他的事件才能继续处理

  • inactive:这个服务目前没有运行

开机预设状态有以下:

  • enabled:开机执行
  • disabled:开机不执行
  • static:不可以自己启动。不过可能会被其他的 enabled 的服务来唤醒(依赖服务)
  • mask:无法被启动,因为已经被强制注销(非删除)。可通过 systemctl unmask 方式改回原本的状态

# 服务启动、关闭与观察联系

习题 1:找到系统中名为 chronyd 的服务,观察此服务状态,并将服务设置为:

  1. 开机不会启动
  2. 现在状态是关闭的情况
[root@study ~]# systemctl status chronyd.service 
* chronyd.service - NTP client/server
	# 开机启动
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
   # 正在运行中
   Active: active (running) since Tue 2020-03-17 10:49:42 CST; 1 day 6h ago
     Docs: man:chronyd(8)
           man:chrony.conf(5)
    Tasks: 1
   CGroup: /system.slice/chronyd.service
           `-933 /usr/sbin/chronyd

Mar 17 10:49:39 study.centos.mrcode systemd[1]: Starting NTP client/server...
Mar 17 10:49:39 study.centos.mrcode chronyd[933]: chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
Mar 17 10:49:39 study.centos.mrcode chronyd[933]: Frequency 0.000 +/- 1000000.000 ppm read from /var/lib/chrony/drift
Mar 17 10:49:42 study.centos.mrcode systemd[1]: Permission denied while opening PID file or unsafe symlink chain: /var/run/chrony/chronyd.pid
Mar 17 10:49:42 study.centos.mrcode systemd[1]: Started NTP client/server.

# 取消开机启动
[root@study ~]# systemctl disable chronyd.service 
Removed symlink /etc/systemd/system/multi-user.target.wants/chronyd.service.
# 取消开机启动,这里其实就是移除了 /etc/systemd/system 该目录下的一个链接文件

# 停止该服务
[root@study ~]# systemctl stop chronyd.service 
[root@study ~]# systemctl status chronyd.service 
* chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:chronyd(8)
           man:chrony.conf(5)

Mar 17 10:49:39 study.centos.mrcode systemd[1]: Starting NTP client/server...
Mar 17 10:49:39 study.centos.mrcode chronyd[933]: chronyd version 3.4 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +SECHASH +IPV6 +DEBUG)
Mar 17 10:49:39 study.centos.mrcode chronyd[933]: Frequency 0.000 +/- 1000000.000 ppm read from /var/lib/chrony/drift
Mar 17 10:49:42 study.centos.mrcode systemd[1]: Permission denied while opening PID file or unsafe symlink chain: /var/run/chrony/chronyd.pid
Mar 17 10:49:42 study.centos.mrcode systemd[1]: Started NTP client/server.
Mar 18 16:53:11 study.centos.mrcode systemd[1]: Stopping NTP client/server...
Mar 18 16:53:11 study.centos.mrcode systemd[1]: Stopped NTP client/server.
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

习题 2:将 cups 服务整个关闭(因为没有打印机安装在服务器上,也没有网络打印机)

[root@study ~]# systemctl status cups.service 
* cups.service - CUPS Printing Service
   Loaded: loaded (/usr/lib/systemd/system/cups.service; enabled; vendor preset: enabled)
   # 书上这里状态是 inactive(dead) 没有运行状态,笔者这里确实在运行状态
   Active: active (running) since Tue 2020-03-17 10:49:55 CST; 1 day 6h ago
 Main PID: 1374 (cupsd)
   CGroup: /system.slice/cups.service
           `-1374 /usr/sbin/cupsd -f

Mar 17 10:49:55 study.centos.mrcode systemd[1]: Started CUPS Printing Service.

# 停止服务
[root@study ~]# systemctl stop cups.service 
Warning: Stopping cups.service, but it can still be activated by:
  cups.path
  cups.socket
# 取消开机启动
[root@study ~]# systemctl disable cups.service 
Removed symlink /etc/systemd/system/multi-user.target.wants/cups.path.
Removed symlink /etc/systemd/system/multi-user.target.wants/cups.service.
Removed symlink /etc/systemd/system/sockets.target.wants/cups.socket.
Removed symlink /etc/systemd/system/printer.target.wants/cups.service.
# 这里一共移除了 4 个连结文件,说明这几个文件可能是相依赖性
[root@study ~]# netstat -tlunp | grep cups
# cups 服务没有被启动,所以没有端口产生

# 尝试启动 cups.socket 监听客户端的需求
[root@study ~]# systemctl start cups.socket
[root@study ~]# systemctl status cups.service cups.socket cups.path 
* cups.service - CUPS Printing Service
   Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2020-03-18 16:57:19 CST; 4min 8s ago
 Main PID: 1374 (code=exited, status=0/SUCCESS)

Mar 17 10:49:55 study.centos.mrcode systemd[1]: Started CUPS Printing Service.
Mar 18 16:57:19 study.centos.mrcode systemd[1]: Stopping CUPS Printing Service...
Mar 18 16:57:19 study.centos.mrcode systemd[1]: Stopped CUPS Printing Service.

* cups.socket - CUPS Printing Service Sockets
   Loaded: loaded (/usr/lib/systemd/system/cups.socket; disabled; vendor preset: enabled)
   Active: active (listening) since Tue 2020-03-17 10:49:38 CST; 1 day 6h ago
   Listen: /var/run/cups/cups.sock (Stream)

Mar 17 10:49:38 study.centos.mrcode systemd[1]: Listening on CUPS Printing Service Sockets.

* cups.path - CUPS Printer Service Spool
   Loaded: loaded (/usr/lib/systemd/system/cups.path; disabled; vendor preset: enabled)
   Active: active (waiting) since Tue 2020-03-17 10:49:38 CST; 1 day 6h ago

Mar 17 10:49:38 study.centos.mrcode systemd[1]: Started CUPS Printer Service Spool.
# 笔者这里和书上又不一样,书上 cups.path 是 inactive(dead) 状态,我这里则是等待状态


# 尝试使用 lp 指令打印
[root@study ~]# echo "testing" | lp
lp: Error - no default destination available.
# 实际上没有打印机,出现错误也正常
[root@study ~]# systemctl status cups.service                       
* cups.service - CUPS Printing Service
   Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled; vendor preset: enabled)
   # 被启动了
   Active: active (running) since Wed 2020-03-18 17:03:17 CST; 41s ago
 Main PID: 23325 (cupsd)
    Tasks: 1
   CGroup: /system.slice/cups.service
           `-23325 /usr/sbin/cupsd -f

Mar 18 17:03:17 study.centos.mrcode systemd[1]: Started CUPS Printing Service.
[root@study ~]# netstat -tlunp | grep cups
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      23325/cupsd         
tcp6       0      0 ::1:631                 :::*                    LISTEN      23325/cupsd 

# 这里竟然被自动启动了,我们刚刚操作命名是 stop 了这个服务
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

上面例子充分演示了很多服务之间是有相依性的,cups 是一种打印服务,会启用 631 port 来提供网络打印机的打印功能。但是我们无需一直启动 631 的端口,因此,多了一个 cups.socket 的服务,这个服务可以在「用户有需要打印时,才会主动唤醒 cups.service」,由于有了这个特性,所以就算事先吧 3 个 cups 的服务都 stop 掉,当用户向其他两个 cups.path、cups.socket 提出要求时, cups.service 就会被唤醒

# 强迫服务注销 mask 的练习

比较正常的做法是:要关闭 cups.service 时,连同其他两个会唤醒 service 的 cups.socket 与 cups.path 都关闭,那就没有事情了。

不正常的做法是:强迫 cups.service 注销,通过 mask 方式

[root@study ~]# systemctl stop cups.service 
Warning: Stopping cups.service, but it can still be activated by:
  cups.socket
  cups.path
[root@study ~]# systemctl mask cups.service 
Created symlink from /etc/systemd/system/cups.service to /dev/null.
[root@study ~]# systemctl status cups.service 
* cups.service
   Loaded: masked (/dev/null; bad)
   Active: inactive (dead) since Wed 2020-03-18 17:11:29 CST; 32s ago
 Main PID: 23325 (code=exited, status=0/SUCCESS)

Mar 18 17:03:17 study.centos.mrcode systemd[1]: Started CUPS Printing Service.
Mar 18 17:11:29 study.centos.mrcode systemd[1]: Stopping CUPS Printing Service...
Mar 18 17:11:29 study.centos.mrcode systemd[1]: Stopped CUPS Printing Service.
[root@study ~]# systemctl start cups.service 
Failed to start cups.service: Unit is masked.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

通过 mask 之后,他的连结文件被连结到了 /dev/null,所以就无法启动了

# 取消注销
[root@study ~]# systemctl unmask cups.service 
Removed symlink /etc/systemd/system/cups.service.
[root@study ~]# systemctl status cups.service 
* cups.service - CUPS Printing Service
   Loaded: loaded (/usr/lib/systemd/system/cups.service; disabled; vendor preset: enabled)
   Active: inactive (dead) since Wed 2020-03-18 17:11:29 CST; 2min 30s ago
 Main PID: 23325 (code=exited, status=0/SUCCESS)

Mar 18 17:03:17 study.centos.mrcode systemd[1]: Started CUPS Printing Service.
Mar 18 17:11:29 study.centos.mrcode systemd[1]: Stopping CUPS Printing Service...
Mar 18 17:11:29 study.centos.mrcode systemd[1]: Stopped CUPS Printing Service.
# 恢复正常了
1
2
3
4
5
6
7
8
9
10
11
12
13

# 观察系统上所有的服务

systemctl [command][--type=TYPE][--all]

command:
	list-units:按 unit 列出目前有启动的 unit。若加上 --all 才会列出没有启动的
	list-unit-files:按 `/usr/lib/systemd/system` 内的文件,将所有文件列表说明
--type:之前提到过的 unit type,主要有 service、socket、target 等
1
2
3
4
5
6
范例 1:列出系统上有启动的 unit
[root@study ~]# systemctl
UNIT                                                                                     LOAD   ACTIVE SUB       DESCRIPTION
proc-sys-fs-binfmt_misc.automount                                                        loaded active waiting   Arbitrary Executable File Formats File System Automount Point
sys-devices-pci0000:00-0000:00:03.0-net-enp0s3.device                                    loaded active plugged   82540EM Gigabit Ethernet Controller (PRO/1000 MT Desktop Adapter)
sys-devices-pci0000:00-0000:00:05.0-sound-card0.device                                   loaded active plugged   82801AA AC'97 Audio Controller
sys-devices-pci0000:00-0000:00:0d.0-ata3-host2-target2:0:0-2:0:0:0-block-sda-sda1.device loaded active plugged   VBOX_HARDDISK 1
...
vsftpd.service  loaded active running   Vsftpd ftp daemon

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

152 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
lines 106-160/160 (END)
# 服务太多了,个别字段含义如下
# UNIT:项目名称,包括各个 unit 的类型(看扩展名)
# LOAD:开机时是否会被加载,默认 systemctl 显示的是有加载的项目
# ACTIVE:目前的状态,续与后续的 SUB 搭配,就是用 systemctl status 观察时,active 项目
# DESCRIPTION:详细描述
# 另外,systemctl 不加参数,预设是 list-units 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 范例 2:列出所有已经安装的 unit 有哪些
[root@study ~]# systemctl list-unit-files 
UNIT FILE                                     STATE   
proc-sys-fs-binfmt_misc.automount             static  
dev-hugepages.mount                           static  
dev-mqueue.mount                              static  
proc-fs-nfsd.mount                            static  
proc-sys-fs-binfmt_misc.mount                 static  
sys-fs-fuse-connections.mount                 static  
sys-kernel-config.mount                       static  
sys-kernel-debug.mount                        static  
tmp.mount                                     disabled
var-lib-nfs-rpc_pipefs.mount                  static  
brandbot.path                                 disabled
cups.path                                     disabled
systemd-ask-password-console.path             static  
systemd-ask-password-plymouth.path            static  
systemd-ask-password-wall.path                static  
session-2.scope                               static  
session-92.scope                              static  
session-c1.scope                              static  
abrt-ccpp.service                             enabled 
abrt-oops.service                             enabled 
# 会将系统上所有的服务都列出来,STATE 则是前面讲到过的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 范例 3:只列出某种类型的 unit
# 这样就只会显示 .service 类型的服务了
[root@study ~]# systemctl list-units --type=service --all
  UNIT                                                  LOAD      ACTIVE   SUB     DESCRIPTION
  abrt-ccpp.service                                     loaded    active   exited  Install ABRT coredump hook
  abrt-oops.service                                     loaded    active   running ABRT kernel log watcher
  abrt-vmcore.service                                   loaded    inactive dead    Harvest vmcores for ABRT
  abrt-xorg.service                                     loaded    active   running ABRT Xorg log watcher
  abrtd.service                                         loaded    active   running ABRT Automated Bug Reporting Tool
  accounts-daemon.service                               loaded    active   running Accounts Service
  alsa-restore.service                                  loaded    inactive dead    Save/Restore Sound Card State
  alsa-state.service                                    loaded    active   running Manage Sound Card State (restore and store)
* apparmor.service                                      not-found inactive dead    apparmor.service

# 查找是否有 cpu 为名的服务
[root@study ~]# systemctl list-units --type=service --all | grep cpu
  cpupower.service                                      loaded    inactive dead    Configure CPU power related settings
# CPU 电源管理机制的服务 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 管理不同的操作环境(target unit)

[root@study ~]# systemctl list-units --type=target --all            
  UNIT                   LOAD      ACTIVE   SUB    DESCRIPTION
  basic.target           loaded    active   active Basic System
  cryptsetup.target      loaded    active   active Local Encrypted Volumes
* dbus.target            not-found inactive dead   dbus.target
  emergency.target       loaded    inactive dead   Emergency Mode
  final.target           loaded    inactive dead   Final Step
  getty-pre.target       loaded    active   active Login Prompts (Pre)
  getty.target           loaded    active   active Login Prompts
  graphical.target       loaded    active   active Graphical Interface
  local-fs-pre.target    loaded    active   active Local File Systems (Pre)
  local-fs.target        loaded    active   active Local File Systems
  multi-user.target      loaded    active   active Multi-User System
  network-online.target  loaded    active   active Network is Online
  network-pre.target     loaded    active   active Network (Pre)
  network.target         loaded    active   active Network
  nfs-client.target      loaded    active   active NFS client services
  nss-lookup.target      loaded    inactive dead   Host and Network Name Lookups
  nss-user-lookup.target loaded    active   active User and Group Name Lookups
  paths.target           loaded    active   active Paths
  remote-fs-pre.target   loaded    active   active Remote File Systems (Pre)
  remote-fs.target       loaded    active   active Remote File Systems
  rescue.target          loaded    inactive dead   Rescue Mode
  rpc_pipefs.target      loaded    active   active rpc_pipefs.target
  rpcbind.target         loaded    active   active RPC Port Mapper
  shutdown.target        loaded    inactive dead   Shutdown
  slices.target          loaded    active   active Slices
  sockets.target         loaded    active   active Sockets
  sound.target           loaded    active   active Sound Card
  swap.target            loaded    active   active Swap
  sysinit.target         loaded    active   active System Initialization
* syslog.target          not-found inactive dead   syslog.target
  time-sync.target       loaded    inactive dead   System Time Synchronized
  timers.target          loaded    active   active Timers
  umount.target          loaded    inactive dead   Unmount All Filesystems

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

33 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
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

笔者这里与书上也不太一样(可能还是因为系统版本的原因,我的比较新一点),有 33 个 target unit,与操作界面相关性较高的 target 主要有下面几个

  • graphical.target:文字 + 图形界面,该项目已包含了下面的 multi-user.target 项目
  • multi-user.target:纯文本模式
  • rescue.target:在无法使用 root 登录的情况下,systemd 在开机时会多加一个额外的暂时系统,与你原本的系统无关。这时就可以取得 root 的权限来维护你的系统。由于是额外的系统,可能需要使用 chroot 方式来取得原有的系统(后续会讲解)
  • emergency.target:紧急处理系统的错误,需要使用 root 登录的情况,在无法使用 rescue.target 时,可以尝试使用该模式
  • shutdown.target:关机流程
  • getty.target:可以设置你需要几个 tty 之类的,如果想要降低 tty 的项目,可以修改该配置文件

按功能分类如下:

  • 正常模式:graphical.target、multi-user.target
  • 救援模式:rescue.target、emergency.target

如何获取当前的模式与修改

systemctl [command] [unit.target]

command:
	get-default:取得目前的 target
	set-default:将 target 设置为默认的操作模式
	isolate:切换到后面指定的操作模式
1
2
3
4
5
6
# 范例 1:我们的测试机器默认是图形界面,先观察是否是图形模式,再将默认模式设置为文字模式
[root@study ~]# systemctl get-default 
graphical.target			# 果真是
[root@study ~]# systemctl set-default multi-user.target 
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
[root@study ~]# systemctl get-default 
multi-user.target
# 已切换到文字模式为默认模式了

# 范例 2:在不重新启动的情况下,将目前的操作环境改为纯文本模式,关掉图形界面
systemctl isolate multi-user.target

# 范例 3:切换到图形界面
systemctl isolate graphical.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

注意:在 service 部分用 start、stop、restart ,在 target 中使用 上述提到的指令,isolate 切换;还提供了几个简单直观的指令使用

systemctl poweroff		# 系统关机
systemctl reboot		# 重新启动
systemctl suspend		# 进入暂停模式
systemctl hibernate		# 进入休眠模式
systemctl rescue		# 强制进入救援模式
systemctl emergency		# 强制进入紧急救援模式
1
2
3
4
5
6
  • suspend:暂停模式

    该模式会将系统的状态数据保存在内存中,然后关闭掉大部分的系统硬件,当用户按下唤醒机器的按钮,系统数据会从内存中恢复,然后重新驱动被大部分关闭的硬件,唤醒速度很快;

  • hibernate:休眠模式

    将系统状态保存到硬盘中,保存完成后,计算机关闭。当用户尝试唤醒系统时,会开始正常工作,然后将保存在硬盘中的系统状态恢复回来。由于数据从硬盘读取,所以唤醒效率与硬盘速度有关

# 分析个服务之间的相依性

本章开始讲到过 systemd 相依性的问题客服,那么,如何追踪某一个 unit 的相依性呢?比如怎么知道 graphical.target 会用到 multi-user.target

systemctl list-dependencies [unit] [--reverse]

-- reverse:反向追踪谁使用这个 unit
1
2
3
# 范例 1:列出目前的 target 环境下,用到什么特别的 unit
[root@study ~]# systemctl get-default 
multi-user.target
[root@study ~]# systemctl list-dependencies 
default.target
* |-abrt-ccpp.service
* |-abrt-oops.service
* |-abrt-vmcore.service
* |-abrt-xorg.service
* |-abrtd.service
* |-atd.service
* |-getty.target
* | `-getty@tty1.service
* |-nfs-client.target
* | |-auth-rpcgss-module.service
* | |-rpc-statd-notify.service
* | `-remote-fs-pre.target
* `-remote-fs.target
*   `-nfs-client.target
*     |-auth-rpcgss-module.service
*     |-rpc-statd-notify.service
*     `-remote-fs-pre.target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

这里不加 unit 则是使用默认的 target,可以看到一颗依赖树,非常直观

# 反向追踪
[root@study ~]# systemctl list-dependencies --reverse 
default.target
* `-graphical.target

# 查看 graphical.target 使用了多少服务
[root@study ~]# systemctl list-dependencies graphical.target
graphical.target
* |-accounts-daemon.service
* |-gdm.service
* |-initial-setup-reconfiguration.service
* |-network.service
* |-rtkit-daemon.service
* |-systemd-update-utmp-runlevel.service
* |-udisks2.service
* `-multi-user.target
*   |-abrt-ccpp.service
*   |-abrt-oops.service
*   |-abrt-vmcore.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 与 systemd 的 deaemon 运行过程相关目录简介

比较重要的 systemd 启动脚本配置文件在 /usr/lib/systemd/system//etc/systemd/system/ 目录下,还有以下目录与系统的 daemon 运行有关:

  • /usr/lib/systemd/system/

    使用 CentOS 官方提供的软件安装后,默认的启动脚本配置文件都放在这里,这里的数据尽量不要修改,要修改时,可以到 /etc/systemd/system/ 下修改

  • /run/systemd/system/

    系统执行过程中所产生的服务脚本,这些脚本的优先顺序比 /usr/lib/systemd/system/

  • /etc/systemd/system/

    管理员根据需求建立的执行脚本,执行优先顺序比 /run/systemd/system/

  • /etc/sysconfig/*

    几乎所有的服务都会将初始化的一些选项设置写入到这个目录下。

    比如 mandb 要更新的 man page 索引中,需要加入的参数就写入到此目录下的 man-db 中。而网络的设置写在 /etc/sysconfig/network-scripts/ ;所以该目录也很重要

  • /var/lib/

    一些会产生数据的服务都会讲它的数据写入到该目录中。

    比如:数据库管理系统 Mariadb 的数据库默认写入到 /var/lib/mysql/ 目录下的

  • /run/:存放了很多 daemon 的暂存文件,包括 lock file 以及 PID file 等

我们知道 systemd 有很多本机会用到的 socket 服务,会产生很多的 socket file,可以通过以下方式知道这些 socket file 的存放位置

[root@study ~]# systemctl list-sockets 
LISTEN                          UNIT                         ACTIVATES
/dev/log                        systemd-journald.socket      systemd-journald.service
/run/dbus/system_bus_socket     dbus.socket                  dbus.service
/run/dmeventd-client            dm-event.socket              dm-event.service
/run/dmeventd-server            dm-event.socket              dm-event.service
/run/lvm/lvmetad.socket         lvm2-lvmetad.socket          lvm2-lvmetad.service
/run/lvm/lvmpolld.socket        lvm2-lvmpolld.socket         lvm2-lvmpolld.service
/run/systemd/initctl/fifo       systemd-initctl.socket       systemd-initctl.service
/run/systemd/journal/socket     systemd-journald.socket      systemd-journald.service
/run/systemd/journal/stdout     systemd-journald.socket      systemd-journald.service
/run/systemd/shutdownd          systemd-shutdownd.socket     systemd-shutdownd.service
/run/udev/control               systemd-udevd-control.socket systemd-udevd.service
/var/run/avahi-daemon/socket    avahi-daemon.socket          avahi-daemon.service
/var/run/cups/cups.sock         cups.socket                  cups.service
/var/run/libvirt/virtlockd-sock virtlockd.socket             virtlockd.service
/var/run/libvirt/virtlogd-sock  virtlogd.socket              virtlogd.service
/var/run/rpcbind.sock           rpcbind.socket               rpcbind.service
0.0.0.0:111                     rpcbind.socket               rpcbind.service
0.0.0.0:111                     rpcbind.socket               rpcbind.service
@ISCSIADM_ABSTRACT_NAMESPACE    iscsid.socket                iscsid.service
@ISCSID_UIP_ABSTRACT_NAMESPACE  iscsiuio.socket              iscsiuio.service
[::]:111                        rpcbind.socket               rpcbind.service
[::]:111                        rpcbind.socket               rpcbind.service
kobject-uevent 1                systemd-udevd-kernel.socket  systemd-udevd.service

23 sockets listed.
Pass --all to see loaded but inactive sockets, too.

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

上面列出了正在监听本地服务需求的 socket file 所在的文件名位置

# 网络服务于端口对应简介

IP 与 PORT 是英特网联机的最重要机制之一,还有各种的通信协议,如 http、ftp;在 /etc/services 里面对应了协议与端口号的映射关系

[root@study ~]# cat /etc/services
# daemon name	port/封包协议	服务说明
ftp             21/tcp
ftp             21/udp          fsp fspd
ssh             22/tcp                          # The Secure Shell (SSH) Protocol
ssh             22/udp                          # The Secure Shell (SSH) Protocol
http            80/tcp          www www-http    # WorldWideWeb HTTP
http            80/udp          www www-http    # HyperText Transfer Protocol
http            80/sctp                         # HyperText Transfer Protocol
https           443/tcp                         # http protocol over TLS/SSL
https           443/udp                         # http protocol over TLS/SSL
https           443/sctp                        # http protocol over TLS/SSL
# 该文件下有大量的数据
1
2
3
4
5
6
7
8
9
10
11
12
13

不建议修改这些端口,除非你想吧这些隐藏起来,不让外部访问到

# 关闭网络服务

当你第一次使用 systemctl 观察本地服务器启动的服务时,会发现有很多 daemon,这是因为 systemd 将许多原本不被列为 daemon 的程序也纳入管理检测范围内,但是那些大部分都属于 Linux 系统基础运行所需的环境,你不清楚的情况下,最好不要去修改他们

除了本地服务之外,要观察网络服务,虽然网络服务默认有 SELinux 管理,不过,还是建议非必要的网络服务就关闭它。基本上会产生一个网络监听端口的程序,就可以称它为网络服务了,可通过如下方式观察网络端口

[root@study ~]# netstat -tlunp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1578/master         
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      2350/sshd: mrcode@p 
tcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTEN      10579/sshd: root@pt 
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd           
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      1975/dnsmasq        
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1378/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1578/master         
tcp6       0      0 ::1:6010                :::*                    LISTEN      2350/sshd: mrcode@p 
tcp6       0      0 ::1:6011                :::*                    LISTEN      10579/sshd: root@pt 
tcp6       0      0 :::555                  :::*                    LISTEN      11573/vsftpd        
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd           
tcp6       0      0 :::22                   :::*                    LISTEN      1378/sshd           
udp        0      0 192.168.122.1:53        0.0.0.0:*                           1975/dnsmasq        
udp        0      0 0.0.0.0:67              0.0.0.0:*                           1975/dnsmasq        
udp        0      0 0.0.0.0:111             0.0.0.0:*                           1/systemd           
udp        0      0 0.0.0.0:33017           0.0.0.0:*                           920/avahi-daemon: r 
udp        0      0 0.0.0.0:669             0.0.0.0:*                           925/rpcbind         
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           920/avahi-daemon: r 
udp6       0      0 :::111                  :::*                                1/systemd           
udp6       0      0 :::669                  :::*                                925/rpcbind 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

比如上面显示 avahi-daemon 服务监听了 5353 和 33017 端口,可以通过 systemctl 查找是否真的有 avahi-daemon 服务

[root@study ~]# systemctl list-units --all | grep avahi-daemon
  avahi-daemon.service                                                                                           loaded    active   running   Avahi mDNS/DNS-SD Stack
  avahi-daemon.socket                                                                                            loaded    active   running   Avahi mDNS/DNS-SD Stack Activation Socket
1
2
3

avahi-daemon 的目的是在局域网进行类似网芳的搜索,因此这个服务可以协助你在区网内随时了解即插即用的设备。包括笔记本电脑等,只要你连上区网,你就能知道谁进来了。问题是,你可能不需要这个协议,关闭它

# 关闭两个服务,并且取消开机启动
[root@study ~]# systemctl stop avahi-daemon.service 
Warning: Stopping avahi-daemon.service, but it can still be activated by:
  avahi-daemon.socket
[root@study ~]# systemctl stop avahi-daemon.socket  
[root@study ~]# systemctl disable avahi-daemon.service avahi-daemon.socket 
Removed symlink /etc/systemd/system/multi-user.target.wants/avahi-daemon.service.
Removed symlink /etc/systemd/system/sockets.target.wants/avahi-daemon.socket.
Removed symlink /etc/systemd/system/dbus-org.freedesktop.Avahi.service.
[root@study ~]# netstat -tlunp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1578/master         
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      2350/sshd: mrcode@p 
tcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTEN      10579/sshd: root@pt 
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd           
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      1975/dnsmasq        
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1378/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1578/master         
tcp6       0      0 ::1:6010                :::*                    LISTEN      2350/sshd: mrcode@p 
tcp6       0      0 ::1:6011                :::*                    LISTEN      10579/sshd: root@pt 
tcp6       0      0 :::555                  :::*                    LISTEN      11573/vsftpd        
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd           
tcp6       0      0 :::22                   :::*                    LISTEN      1378/sshd           
udp        0      0 192.168.122.1:53        0.0.0.0:*                           1975/dnsmasq        
udp        0      0 0.0.0.0:67              0.0.0.0:*                           1975/dnsmasq        
udp        0      0 0.0.0.0:111             0.0.0.0:*                           1/systemd           
udp        0      0 0.0.0.0:669             0.0.0.0:*                           925/rpcbind         
udp6       0      0 :::111                  :::*                                1/systemd           
udp6       0      0 :::669                  :::*                                925/rpcbind  
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

一般来说,你本地服务器至少需要 25 端口,而 22 端口最好加上防火墙来管理远程联机登录比较妥当。555 端口是我们前面练习测试修改的。这样的系统能够被黑的机会已经少很多了。