systemd.socket 中文手册

译者:金步国


版权声明

本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。

其他作品

本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:

联系方式

由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。


手册索引 . 指令索引systemd-231

名称

systemd.socket — 套接字单元配置

大纲

socket.socket

描述

以 ".socket" 为后缀的单元文件, 封装了一个用于进程间通信的套接字(socket)或管道(FIFO), 以支持基于套接字的启动。

本手册列出了所有专用于此类单元的配置选项(亦称"配置指令"或"单元属性")。 systemd.unit(5) 中描述了通用于所有单元类型的配置选项, 它们位于 "[Unit]" 与 "[Install]" 小节。 此类单元专用的配置选项位于 "[Socket]" 小节。

其他相关的选项还包括: systemd.exec(5) 中的选项定义了 ExecStartPre=, ExecStartPost=, ExecStopPre=, ExecStopPost= 命令的执行环境; systemd.kill(5) 中的选项定义了进程的结束方式; systemd.resource-control(5) 中的选项定义了进程的资源限制。

每个套接字单元都必须有一个与其匹配的服务单元(详见 systemd.service(5) 手册), 以处理该套接字上的接入流量。 匹配的 .service 单元名称默认与对应的 .socket 单元相同, 但是也可以通过 Service= 选项(见下文)明确指定。 如果 Accept=no (见下文), 那么匹配的 .service 单元必须要么与 .socket 单元同名, 要么必须通过 Service= 选项明确指定。 如果 Accept=yes (见下文), 那么匹配的 .service 单元必须是与 .socket 单元同名的模版单元。 举例来说也就是: 当 Accept=no 时, foo.service 可以与 foo.socket 匹配; 而当 Accept=yes 时, 仅有 foo@.service 可以与 foo.socket 匹配。

除非在 "[Unit]" 小节中明确设置了 DefaultDependencies=no , 否则每个套接字单元都将隐含如下四个依赖关系:Requires=sysinit.target, After=sysinit.target 以及 Conflicts=shutdown.target, Before=shutdown.target 。 这样可以确保套接字单元在完成基础系统初始化之后再启动,并且在关闭系统之前先干净的结束。 只有那些必须在系统启动早期建立的套接字,或者必须在系统关闭的末尾才能结束的套接字, 才可以设置 DefaultDependencies=no

每个套接字单元都自动隐含对匹配的服务单元的 Before= 依赖。 举例来说,相当于 foo.socket 单元文件内隐含有一行 Before=foo.service 。 注意,foo.socket 单元文件内并不隐含 WantedBy=foo.serviceRequiredBy=foo.service 依赖。 这就意味着匹配的服务单元可以在该套接字不存在的情况下启动(此时服务需要自己创建并打开所需的套接字)。 为了避免这个问题, 可以向 foo.service 服务单元文件中 明确添加一个 Requires=foo.socket 依赖。

套接字单元可用于实现服务的按需启动以及并行启动。

注意,要想配置为基于套接字启动, 守护进程必须有能力从 systemd 接手已经创建好的套接字。 这既可以通过调 sd_listen_fds(3) 接口实现,也可以通过传统的 inetd(8) 风格的套接字传递方式实现(需要在服务单元文件中设置 StandardInput=socket )。

自动依赖

socket 单元会自动添加对匹配的 service 单元的 Before= 依赖。

引用了文件系统路径(例如UNIX套接字或FIFO)的 socket 单元, 会自动添加对访问该路径所需的所有 mount 单元的 Requires=After= 依赖。

使用了 BindToDevice= 选项的 socket 单元, 会自动添加对封装了目标网络接口的 device 单元的 BindsTo=After= 依赖。

除非明确设置了 DefaultDependencies=no , 否则 socket 单元都自动隐含如下依赖: Before=sockets.target, After=sysinit.target, Requires=sysinit.target, Before=shutdown.target, Conflicts=shutdown.target 。 这样可以确保普通的套接字单元:(1)在系统启动时先于普通服务启动, (2)在系统关闭之前先被干净的停止。

systemd.exec(5)systemd.resource-control(5) 中的某些资源限制选项也会自动隐含的添加一些其他的依赖关系。

选项

套接字单元文件中必须包含一个 [Socket] 小节, 其中包含了套接字或管道的相关信息。 能在 [Socket] 小节中使用的选项, 有许多亦可用于其他类型的单元文件(参见 systemd.exec(5)systemd.kill(5) 手册)。 这里只列出仅能用于 [Socket] 小节的选项(亦称"指令"或"属性"):

ListenStream=, ListenDatagram=, ListenSequentialPacket=

分别为 字节流(SOCK_STREAM)、 数据报(SOCK_DGRAM)、 顺序包(SOCK_SEQPACKET) 指定套接字的监听地址(还可能包括端口)。可以接受的地址格式如下:

如果地址以 "/" 开头, 那么将被视为文件系统上的一个 UNIX套接字(AF_UNIX)。

如果地址以 "@" 开头, 那么将被视为抽象名字空间内的一个 UNIX套接字(AF_UNIX)。 "@" 将会在绑定前被替换为 NUL 字符, 详见 unix(7) 手册。

如果地址是一个纯数字, 那么将被视为在IPv6地址上监听的一个端口号。 取决于 BindIPv6Only= 选项(见下文)的设置, 绑定的端口可能同时接受IPv6与IPv4连接。

如果地址是一个符合"v.w.x.y:z"格式的字符串, 那么将被视为在指定的IPv4地址"v.w.x.y"的"z"端口上监听。

如果地址是一个符合"[x]:y"格式的字符串, 那么将被视为在指定的IPv6地址"x"的"y"端口上监听。 取决于 BindIPv6Only= 选项(见下文)的设置, 绑定的端口可能同时接受IPv6与IPv4连接。

注意,顺序包 SOCK_SEQPACKET (也就是 ListenSequentialPacket=) 仅可用于 UNIX套接字(AF_UNIX)。 当字节流 SOCK_STREAM (也就是 ListenStream=) 应用于IP套接字时,其含义是TCP套接字, 当数据报 SOCK_DGRAM (也就是 ListenDatagram=) 应用于IP套接字时,其含义是UDP套接字。

如果多次使用这些选项, 那么当其中任意一个套接字上有流量进入时, 对应的服务都将被启动, 并且所有这些选项列出的套接字都将被传递给对应的服务, 无论这些套接字上是否有流量进入。 如果为某个选项指定了一个空字符串, 则表示清空该选项之前设置的所有监听地址。

通过使用 Service= 选项, 可以让多个套接字单元对应到同一个服务单元, 也就是由同一个服务单元接收多个套接字单元中配置的所有套接字。 同一个套接字单元内配置的多个套接字按其在单元文件中出现的顺序传递, 但是在多个套接字单元之间并不遵守任何顺序。

如果在此处配置了某个IP地址, 我们通常希望在对应的网络接口实际可用之前就开始监听 (甚至不管该接口是否真的可用)。 如果这正是你所期盼的效果, 那么可以使用 FreeBind= 选项(见下文)达到此目的。

ListenFIFO=

设置一个要监听的文件系统管道(FIFO), 必须使用绝对路径。 该选项的行为与 ListenDatagram= 选项非常相似。

ListenSpecial=

设置一个要监听的特殊文件, 必须使用绝对路径。 该选项的行为与 ListenFIFO= 选项非常相似。 此选项可用于监听 /dev 中的字符设备文件以及 /proc/sys 中的特殊文件。

ListenNetlink=

设置一个要监听的 Netlink 套接字。 必须设为一个合理的 AF_NETLINK 名称(例如 auditkobject-uevent), 并且可以在其末尾附加一个可选的"Netlink多播组ID(一个整数)"后缀, AF_NETLINK 名称与其后缀之间以空格分隔。 该选项的行为与 ListenDatagram= 选项非常相似。

ListenMessageQueue=

设置一个要监听的 POSIX 消息队列。 必须设为一个合理的 POSIX 消息队列名称(以"/"开头)。 该选项的行为与 ListenFIFO= 选项非常相似。 在 Linux 系统上,POSIX 消息队列描述符实际上就是一个文件描述符, 并且可以在进程之间继承。

ListenUSBFunction=

设置一个监听的 USB FunctionFS 端点位置以实现 USB gadget 功能, 必须使用绝对路径。 此处设置的路径将被用于打开 FunctionFS 端点 ep0 (其行为与前述的 ListenFIFO= 选项类似)。 如果使用了此选项, 那么对应的 service 单元必须设置了 USBFunctionDescriptors=USBFunctionStrings= 选项。

SocketProtocol=

指定套接字的协议: udplite 表示 UDP-Lite(IPPROTO_UDPLITE); sctp 表示 SCTP(IPPROTO_SCTP)。

BindIPv6Only=

控制 IPV6_V6ONLY 套接字选项(详见 ipv6(7) 手册),可设为 default, both, ipv6-only 之一。 both 表示该 IPv6 套接字既可以通过 IPv4 访问,也可以通过 IPv6 访问; 而 ipv6-only 则表示仅可以通过 IPv6 访问。 默认值 default 则表示使用 /proc/sys/net/ipv6/bindv6only 中的设置 (默认值等价于 both)。

Backlog=

设置半链接队列的最大长度,也就是最大允许多少个连接处于"等待接入"的状态。 必须设为一个正整数。 此选项仅对字节流(SOCK_STREAM)以及顺序包(SOCK_SEQPACKET)套接字有意义。 详见 listen(2) 手册。默认值为 SOMAXCONN(128)

BindToDevice=

设置 SO_BINDTODEVICE 套接字选项(详见 socket(7) 手册), 也就是将套接字绑定到特定的网络接口。 如果设置了此选项,那么仅接收指定的网络接口上的流量, 并且会自动创建到该网络接口的 device 单元(systemd.device(5)) 的依赖关系 (参见上面"自动依赖"小节)。

SocketUser=, SocketGroup=

设置 AF_UNIX 套接字文件与 FIFO 管道文件的属主与属组。 默认未设置这两个选项, 表示文件的属主与属组都是root(运行于系统上下文) 或调用systemd的用户及其属组(运行于用户上下文)。 如果仅指定了用户,那么属组将被自动设为该用户的默认组(主组)。

SocketMode=

设置创建文件节点时的默认访问模式, 仅用于文件系统上的套接字文件与管道文件。 默认值是 0666 。

DirectoryMode=

当监听文件系统上的套接字或管道时, 将会自动创建所需的父目录。 此选项设置了创建父目录时的默认访问模式。 默认值是 0755 。

Accept=

若设为 yes , 则会为每个进入的连接派生一个服务实例, 并且仅将该连接传递给服务实例。 若设为 no(默认值), 则会将套接字自身传递给匹配的服务单元, 并且仅为所有进入的连接派生单独一个服务实例。 此选项对数据报(SOCK_DGRAM)套接字与管道(FIFO)没有意义 (相当于始终设为 no)。 出于性能考虑, 守护进程应该改造为仅使用 Accept=no 的设置。 监听 AF_UNIX 套接字的守护进程可以(但非必须)调用 close(2) 关闭套接字, 但是禁止删除文件系统上的套接字文件。 当 Accept=no 时, 守护进程应该禁止调用 shutdown(2) 关闭套接字; 而当 Accept=yes 时则可以(但非必须)这么做。 设置 Accept=yes 的唯一目的 在于可以不经修改的直接使用为 inetd(8) 设计的守护进程。

对于 IPv4 与 IPv6 连接来说,REMOTE_ADDR 环境变量将会包含远端的IP地址, 而 REMOTE_PORT 环境变量则会包含远端端口。 变量值的格式与 CGI 中使用的格式相同。 而对于 SOCK_RAW 来说,端口就是IP协议。

Writable=

仅可与 ListenSpecial= 一起使用, 表示以什么模式打开指定的文件。 设为 yes 表示以读写模式打开; 设为 no(默认值) 表示以只读模式打开。

MaxConnections=

Accept=yes 时, 允许同时服务的最大连接数量, 也就是允许派生的最大服务实例数量。 若有超出该数量的连接进入,则会被拒绝, 只到有至少一个正在被服务的连接退出。 当 Accept=no 时,此选项没有意义。 默认值是 64 。

KeepAlive=

若设为 yes 则表示在该套接字的所有TCP连接上启用"KeepAlive"检测。 所谓"KeepAlive"检测,其含义是,若某个TCP连接空闲(持续没有任何数据交换)超过指定的时间, 则自动发送"KeepAlive"消息要求对方确认,以判断对方主机是否崩溃或网络不可达。 默认空闲时长取决于 /proc/sys/net/ipv4/tcp_keepalive_time 的设置(默认为2小时)。 此选项实际上是设置了 SO_KEEPALIVE 套接字选项的值。 详见 socket(7)TCP Keepalive HOWTO 文档。 默认值 no 则表示不发送"KeepAlive"消息。

KeepAliveTimeSec=

设置开始发送"KeepAlive"消息前允许TCP连接空闲的秒数。此选项实际上是设置了 TCP_KEEPIDLE 套接字选项的值。 如果某个TCP连接空闲(持续没有任何数据交换)超过了这个秒数,则自动发送"KeepAlive"消息要求对方确认。 详见 socket(7)TCP Keepalive HOWTO 文档。 默认值为 7200 秒。

KeepAliveIntervalSec=

设置两次发送"KeepAlive"消息之间的间隔秒数。 也就是如果对方没有回应"KeepAlive"消息的话,隔多少秒之后再次发送"KeepAlive"消息。 此选项实际上是设置了 TCP_KEEPINTVL 套接字选项的值。 详见 socket(7)TCP Keepalive HOWTO 文档。 默认值为 75 秒。

KeepAliveProbes=

设置最多发送多少个"KeepAlive"消息。 超过这个数量之后,若依然没有收到回应,则认为对方主机已经崩溃或网络不可达。 此选项实际上是设置了 TCP_KEEPCNT 套接字选项的值。 详见 socket(7)TCP Keepalive HOWTO 文档。 默认值为 9 个。

NoDelay=

设置是否"立即发送"数据。此选项实际上是设置了 TCP_NODELAY 套接字选项的值(详见 tcp(7) 手册)。默认值 no 表示启用 TCP Nagle's 算法, 也就是将多个小数据包组合为一个大数据包发送,以提高网络带宽的利用效率。 但是这样做的缺点是可能会增加数据包的发送延迟。 不适合频繁发送小包且对实时性要求较高的应用(例如网络游戏)。

Priority=

设置从此套接字发送的数据包的网络优先级,必须设为一个整数。 此选项实际上是设置了 SO_PRIORITY 套接字选项的值。 详见 socket(7) 手册。

DeferAcceptSec=

若设置此选项,则必须设为一个整数(秒数), 表示只在确实有应用层数据到达这个套接字的时候, 才会唤醒套接字的监听进程, 而不是在建立连接之后(也就是完成三次握手之后)立即被唤醒, 同时内核将会忽略不含任何数据的初始ACK包。 此选项实际上是设置了 TCP_DEFER_ACCEPT 套接字选项的值。 详见 tcp(7) 手册。 此处设置的秒数表示内核在回退到常规行为(正常处理不含任何数据的初始ACK包)前, 最多可以花多少秒等候应用层数据的到达。 对于需要客户端首先发送数据的网络服务(例如HTTP服务器)来说, 使用此选项可以明显提升运行性能, 因为服务进程只在确实有客户端数据进入时才会被唤醒。

如果客户端也开启了 TCP_DEFER_ACCEPT 选项, 那么建立初始连接所花的时间将会被降低, 因为客户端内核将会在本该发送不含任何数据的初始ACK包的时候(也就是第三次握手), 直接发送应用层数据。

此选项默认未设置,表示默认禁用此特性。

ReceiveBuffer=, SendBuffer=

设置套接字的接收与发送缓冲区的大小, 可以使用 K, M, G 后缀(以1024为基数)。 此两个选项实际上是设置了 SO_RCVBUF 与 SO_SNDBUF 套接字选项的值。 详见 socket(7) 手册。

IPTOS=

设置从该套接字发送的IP包的 Type-Of-Service 字段的值, 此选项实际上是设置了 IP_TOS 套接字选项的值。 详见 ip(7) 手册。 必须设为一个整数或 low-delay, throughput, reliability, low-cost 之一。

IPTTL=

设置从该套接字发送的IPv4包的 Time-To-Live 字段或IPv6包的 Hop-Count 字段的值, 必须设为一个整数。 此选项实际上是设置了 IP_TTL 或 IPV6_UNICAST_HOPS 套接字选项的值。 详见 ip(7)ipv6(7) 手册。

Mark=

设置从该套接字发送的IP包的防火墙标记(mark),必须设为一个整数, 防火墙逻辑可根据此标记对包进行过滤。 此选项实际上是设置了 SO_MARK 套接字选项的值, 详见 iptables(8) 手册。

ReusePort=

若设为 yes 则允许多个套接字 bind(2) 到同一个TCP或UDP端口。 此选项实际上是设置了 SO_REUSEPORT 套接字选项的值,详见 socket(7) 手册。

SmackLabel=, SmackLabelIPIn=, SmackLabelIPOut=

设置一个字符串值。 分别控制 "security.SMACK64", "security.SMACK64IPIN", "security.SMACK64IPOUT" 扩展属性的值。 也就是分别设置 管道(FIFO)的安全标签、进入流量的安全标签、发出流量的安全标签。 详见 Smack.txt 内核文档。

SELinuxContextFromNet=

若设为 yes 则 systemd 将尝试根据网络对端的信息 猜测出实例化服务的SELinux标签。 注意, 仅有"安全标签"是根据网络对端信息猜测出来的, 而SELinux上下文中的其他部分, 则要么来自于被此套接字单元触发的目标二进制文件, 要么来自于 SELinuxContext= 选项的值。 此选项仅在 Accept=yes 并且已启用了 MLS/MCS SELinux 策略时才有意义。 默认值是 "no"

PipeSize=

设置管道(FIFO)缓冲区大小(字节), 可以使用以1024为基数的 K, M, G 后缀。 详见 fcntl(2) 手册。

MessageQueueMaxMessages=, MessageQueueMessageSize=

在创建消息队列时,分别设置 mq_maxmsg 与 mq_msgsize 字段的值, 必须设为整数。 注意,这两个选项必须同时设置或者同时不设置,不允许仅设置其中一个。 详见 mq_setattr(3) 手册。

FreeBind=

若设为 yes 则可以将此套接字绑定到非本地IP地址。 这样就可以在指定的IP地址实际可用之前先监听它。 此选项实际上是设置了 IP_FREEBIND 套接字选项的值。 出于健壮性考虑, 当你希望将套接字绑定到特定的IP地址时, 应该将此选项设为 yes 。 默认值为 no

Transparent=

可设为 yes 或 no(默认) 。 此选项实际上是设置了 IP_TRANSPARENT 套接字选项的值。

Broadcast=

可设为 yes 或 no(默认) , 表示是否允许发送广播包。 此选项实际上是设置了 SO_BROADCAST 套接字选项的值。

PassCredentials=

可设为 yes 或 no(默认) , 表示是否允许 AF_UNIX 套接字 接收对端进程在辅助消息中发送的证书。 此选项实际上是设置了 SO_PASSCRED 套接字选项的值。

PassSecurity=

可设为 yes 或 no(默认) 。 表示是否允许 AF_UNIX 套接字接 收对端进程在辅助消息中发送的安全上下文。 此选项实际上是设置了 SO_PASSSEC 套接字选项的值。

TCPCongestion=

设置TCP拥塞控制算法。 必须设为 "westwood", "veno", "cubic", "lp" 之一, 或者内核IP栈支持的其他算法。 此选项仅对字节流(SOCK_STREAM)套接字有意义。

ExecStartPre=, ExecStartPost=

设置在创建与绑定监听套接字/管道之前、之后执行的命令行(命令+参数)。 命令行必须以一个绝对路径表示的可执行文件开始, 并且其后的那些参数将依次作为"argv[1] argv[2] ..."传递给被执行的进程。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 这两个选项与 systemd.service(5) 中的同名选项类似, 遵守的语法规则也相同。

ExecStopPre=, ExecStopPost=

设置在关闭与删除监听套接字/管道之前、之后执行的命令行(命令+参数)。 命令行必须以一个绝对路径表示的可执行文件开始,并且其后的那些参数将依次作为"argv[1] argv[2] ..."传递给被执行的进程。 如果设置了多个命令行,那么这些命令行将以其在单元文件中出现的顺序依次执行。 这两个选项与 systemd.service(5) 中的 ExecStartPre= 选项类似,遵守的语法规则也相同。

TimeoutSec=

设置等候 ExecStartPre=, ExecStartPost=, ExecStopPre=, ExecStopPost= 执行完成的最长时间限制。 如果某个命令执行超时,那么该套接字/管道将被视为失败并且会被强制关闭并删除。 所有正在执行中的命令都可以通过 SIGTERM 信号终止, 并且如果继续等待此处设置的时长之后仍未终止, 那么将使用 SIGKILL 信号强制终止(参见 systemd.kill(5) 中的 KillMode= 选项)。 若设为一个无单位后缀的纯整数,则表示秒数。 否则可以设为例如"5min 20s"这样的时长。 设为 "0" 表示永不超时。 默认值是 DefaultTimeoutStartSec= 选项的值(参见 systemd-system.conf(5) 手册)。

Service=

设置当有流量进入时需要启动的服务单元的名称。 仅可用于 Accept=no 的套接字。 默认值是与套接字单元自身同名的服务单元(剔除后缀)。 在大多数情况下,不需要明确设置此选项。 设置此选项可能导致自动添加额外的依赖关系 (参见上面的"自动依赖"小节)。

RemoveOnStop=

若设为 yes 则此套接字单元创建的所有文件 都将在该单元停止后被删除。 此选项仅对文件系统上的 AF_UNIX套接字、POSIX消息队列、管道(FIFO)、 以及指向这些文件的 Symlinks= 软连接有意义。 通常反对使用此选项, 因为即使套接字单元已经被停止, 对应的服务单元也可能还在继续运行。 默认值是 no 。

Symlinks=

设置在文件系统上创建 AF_UNIX套接字、POSIX消息队列、管道(FIFO)文件的时候, 同时创建指向该文件的软连接。 此选项的参数是一个文件系统路径列表,表示软连接的路径。 设置此选项之后,就可以随着套接字的生命周期一起管理其别名(软连接)。 此选项仅可用于仅配置了一个 AF_UNIX套接字、POSIX消息队列、管道(FIFO)的单元。 默认值为空。

FileDescriptorName=

为该单元封装的所有文件描述符取一个名字。 这有助于已启动的服务定位特定的文件描述符 (如果传递了多个文件描述符的话)。 服务单元可以使用 sd_listen_fds_with_names(3) 为接收到的文件描述符取得此处设置的名称。 名称仅可包含除控制字符与冒号(:)之外的ASCII字符, 且不能超过255个字符。 如果未设置此选项, 那么默认的名称将等于此单元的名称 (包括 .socket 后缀)。

TriggerLimitIntervalSec=, TriggerLimitBurst=

设置该套接字单元的启动频率限制。 TriggerLimitIntervalSec= 用于设置时长,设为 0 表示不作限制。默认值为2秒。 可以使用 "us", "ms", "s", "min", "h" 等时间后缀(参见 systemd.time(7) 手册)。 TriggerLimitBurst= 用于设置在一段给定的时长内,最多允许启动多少次,设为 0 表示不作限制。 如果 Accept=yes ,那么默认值是 200 次(也就是默认在2秒内最多允许启动200次), 否则默认值是 20 次(也就是默认在2秒内最多允许启动20次)。 一旦触碰到了启动频率限制,那么该套接字单元将立即进入失败(failed)状态, 并且直到该套接字单元下次重启之前,都不能接受任何连接。 注意,在服务排队启动之前,此限制就已经生效了。

更多选项参见 systemd.exec(5)systemd.kill(5) 手册。

参见

systemd(1), systemctl(1), systemd.unit(5), systemd.exec(5), systemd.kill(5), systemd.resource-control(5), systemd.service(5), systemd.directives(7), sd_listen_fds(3), sd_listen_fds_with_names(3)

更多详情,参见"systemd for Developers"系列: Socket Activation, Socket Activation, part II, Converting inetd Services, Socket Activated Internet Services and OS Containers.