1--- 2title: Running Services After the Network Is Up 3category: Concepts 4layout: default 5SPDX-License-Identifier: LGPL-2.1-or-later 6--- 7 8# Network configuration synchronization points 9 10systemd provides three target units related to network configuration: 11 12## Network pre-configuration: `network-pre.target` 13 14`network-pre.target` is used to order services before any network interfaces 15start to be configured. Its primary purpose is for usage with firewall services 16that want to establish a firewall *before* any network interface is up. 17 18`network-pre.target` is a passive unit: it cannot be started directly and it is 19not pulled in by the the network management service, but instead a service that 20wants to run before it must pull it in. Network management services hence 21should set `After=network-pre.target`, but not `Wants=network-pre.target` or 22`Requires=network-pre.target`. Services that want to be run before the network 23is configured should use `Before=network-pre.target` and 24`Wants=network-pre.target`. This way, unless there's actually a service that 25needs to be ordered before the network is up, this target is not pulled in, 26avoiding an unnecessary synchronization point. 27 28## Network management services: `network.target` 29 30`network.target` indicates that the network management stack has been started. 31Ordering after it it has little meaning during start-up: whether any network 32interfaces are already configured when it is reached is not defined. 33 34Its primary purpose is for ordering things properly at shutdown: since the 35shutdown ordering of units in systemd is the reverse of the startup ordering, 36any unit that has `After=network.target` can be sure that it is *stopped* 37before the network is shut down when the system is going down. This allows 38services to cleanly terminate connections before going down, instead of losing 39ongoing connections leaving the other side in an undefined state. 40 41Note that `network.target` is a passive unit: you cannot start it directly and 42it is not pulled in by any services that want to make use of the network. 43Instead, it is pulled in by the network management services 44themselves. Services using the network should hence simply place an 45`After=network.target` stanza in their unit files, without 46`Wants=network.target` or `Requires=network.target`. 47 48## Network connectivity has been estabilished: `network-online.target` 49 50`network-online.target` is a target that actively waits until the network is 51"up", where the definition of "up" is defined by the network management 52software. Usually it indicates a configured, routable IP address of some 53kind. Its primary purpose is to actively delay activation of services until the 54network has been set up. 55 56It is an active target, meaning that it may be pulled in by the services 57requiring the network to be up, but is not pulled in by the network management 58service itself. By default all remote mounts defined in `/etc/fstab` make use 59of this service, in order to make sure the network is up before attempts to 60connect to a network share are made. Note that normally, if no service requires 61it and if no remote mount point is configured, this target is not pulled into 62the boot, thus avoiding any delays during boot should the network not be 63available. It is strongly recommended not to make use of this target too 64liberally: for example network server software should generally not pull this 65in (since server software generally is happy to accept local connections even 66before any routable network interface is up). Its primary purpose is network 67client software that cannot operate without network. 68 69For more details about those targets, see the 70[systemd.special(7)](http://www.freedesktop.org/software/systemd/man/systemd.special.html) 71man page. 72 73## Compatibility with SysV init 74 75LSB defines a `$network` dependency for legacy init scripts. Whenever systemd 76encounters a `$network` dependency in LSB headers of init scripts it will 77translate this to `Wants=` and `After=` dependencies on 78`network-online.target`, staying relatively close to traditional LSB behaviour. 79 80# Discussion 81 82The meaning of `$network` is defined [only very 83unprecisely](http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/facilname.html) 84and people tend to have different ideas what it is supposed to mean. Here are a 85couple of ideas people came up with so far: 86 87* The network management software is up. 88* All "configured" network interfaces are up and an IP address has been assigned to each. 89* All discovered local hardware interfaces that have a link beat have an IP address assigned, independently whether there is actually any explicit local configuration for them. 90* The network has been set up precisely to the level that a DNS server is reachable. 91* Same, but some specific site-specific server is reachable. 92* Same, but "the Internet" is reachable. 93* All "configured" ethernet devices are up, but all "configured" PPP links which are supposed to also start at boot don't have to be yet. 94* A certain "profile" is enabled and some condition of the above holds. If another "profile" is enabled a different condition would have to be checked. 95* Based on the location of the system a different set of configuration should be up or checked for. 96* At least one global IPv4 address is configured. 97* At least one global IPv6 address is configured. 98* At least one global IPv4 or IPv6 address is configured. 99* And so on and so on. 100 101All these are valid approaches to the question "When is the network up?", but 102none of them would be useful to be good as generic default. 103 104Modern networking tends to be highly dynamic: machines are moved between 105networks, network configuration changes, hardware is added and removed, virtual 106networks are set up, reconfigured, and shut down again. Network connectivity is 107not unconditionally and continuously available, and a machine is connected to 108different networks at different times. This is particularly true for mobile 109hardware such as handsets, tablets, and laptops, but also for embedded and 110servers. Software that is written under the assumption that network 111connectivity is available continuously and never changes is hence not 112up-to-date with reality. Well-written software should be able to handle dynamic 113configuration changes. It should react to changing network configuration and 114make the best of it. If it cannot reach a server it must retry. If network 115configuration connectivity is lost it must not fail catastrophically. Reacting 116to local network configuration changes in daemon code is not particularly 117hard. In fact many well-known network-facing services running on Linux have 118been doing this for decades. A service written like this is robust, can be 119started at any time, and will always do the best of the circumstances it is 120running in. 121 122`$network` / `network-online.target` is a mechanism that is required only to 123deal with software that assumes continuous network is available (i.e. of the 124simple not-well-written kind). Which facet of it it requires is undefined. An 125IMAP server might just require a certain IP to be assigned so that it can 126listen on it. OTOH a network file system client might need DNS up, and the 127service to contact up, as well. What precisely is required is not obvious and 128can be different things depending on local configuration. 129 130A robust system boots up independently of external services. More specifically, 131if a network DHCP server does not react, this should not slow down boot on most 132setups, but only for those where network connectivity is strictly needed (for 133example, because the host actually boots from the network). 134 135# FAQ 136 137## How do I make sure that my service starts after the network is *really* online? 138 139That depends on your setup and the services you plan to run after it (see 140above). If you need to delay you service after network connectivity has been 141established, include 142 143```ini 144After=network-online.target 145Wants=network-online.target 146``` 147 148in the `.service` file. 149 150This will delay boot until the network management software says the network is "up". 151For details, see the next question. 152 153## What does "up" actually mean? 154 155The services that are ordered before `network-online.target` define it's 156meaning. *Usually* means that all configured network devices are up and have an 157IP address assigned, but details may vary. In particular, configuration may 158affect which interfaces are taken into account. 159 160`network-online.target` will time out after 90s. Enabling this might 161considerably delay your boot even if the timeout is not reached. 162 163The right "wait" service must be enabled: 164`NetworkManager-wait-online.service` if `NetworkManager` is used to configure 165the network, `systemd-networkd-wait-online.service` if `systemd-networkd` is 166used, etc. `systemd-networkd.service` has 167`Also=systemd-networkd-wait-online.service` in its `[Install]` section, so when 168`systemd-networkd.service` is enabled, `systemd-networkd-wait-online.service` 169will be enabled too, which means that `network-online.target` will include 170`systemd-networkd-wait-online.service` when and only when 171`systemd-networkd.service` is enabled. `NetworkManager-wait-online.service` is 172set up similarly. This means that the "wait" services do not need to be enabled 173explicitly. They will be enabled automatically when the "main" service is 174enabled, though they will not be *used* unless something else pulls in 175`network-online.target`. 176 177To verify that the right service is enabled (usually only one should be): 178```console 179$ systemctl is-enabled NetworkManager-wait-online.service systemd-networkd-wait-online.service 180disabled 181enabled 182``` 183 184## Should `network-online.target` be used? 185 186Please note that `network-online.target` means that the network connectivity 187*has been* reached, not that it is currently available. By the very nature and 188design of the network, connectivity may briefly or permanently disappear, so 189for reasonable user experience, services need to handle temporary lack of 190connectivity. 191 192If you are a developer, instead of wondering what to do about `network.target`, 193please just fix your program to be friendly to dynamically changing network 194configuration. That way you will make your users happy because things just 195start to work, and you will get fewer bug reports. You also make the boot 196faster by not delaying services until network connectivity has been 197established. This is particularly important for folks with slow address 198assignment replies from a DHCP server. 199 200Here are a couple of possible approaches: 201 2021. Watch rtnetlink and react to network configuration changes as they 203 happen. This is usually the nicest solution, but not always the easiest. 2042. If you write a server: listen on `[::]`, `[::1]`, `0.0.0.0`, and `127.0.0.1` 205 only. These pseudo-addresses are unconditionally available. If you always 206 bind to these addresses you will have code that doesn't have to react to 207 network changes, as all you listen on is catch-all and private addresses. 2083. If you write a server: if you want to listen on other, explicitly configured 209 addresses, consider using the `IP_FREEBIND` sockopt functionality of the 210 Linux kernel. This allows your code to bind to an address even if it is not 211 actually (yet or ever) configured locally. This also makes your code robust 212 towards network configuration changes. This is provided as `FreeBind=` 213 for systemd services, see 214 [systemd.socket(5)](http://www.freedesktop.org/software/systemd/man/systemd.socket.html). 215 216An exception to the above recommendations is services which require network 217connectivity, but do not delay system startup. An example may be a service 218which downloads package updates into a cache (to be used at some point in the 219future by the package management software). Such a service may even start 220during boot, and pull in and be ordered after `network-online.target`, but as 221long as it is not ordered before any unit that is part of the default target, 222it does not delay boot. It is usually easier to write such a service in a 223"simplistic" way, where it doesn't try to wait for the network connectivity to 224be (re-)established, but is instead started when the network has connectivity, 225and if the network goes away, it fails and relies on the system manager to 226restart it if appropriate. 227 228## Modyfing the meaning of `network-online.target` 229 230As described above, the meaning of this target is defined first by which 231implementing services are enabled (`NetworkManager-wait-online.service`, 232`systemd-networkd-wait-online.service`, …), and second by the configuration 233specific to those services. 234 235For example, `systemd-networkd-wait-online.service` will wait until all 236interfaces that are present and managed by 237[systemd-networkd.service(8)](http://www.freedesktop.org/software/systemd/man/systemd-networkd.service.html). 238are fully configured or failed and at least one link is online; see 239[systemd-networkd-wait-online.service(8)](http://www.freedesktop.org/software/systemd/man/systemd-networkd-wait-online.service.html) 240for details. Those conditions are affected by the presence of configuration 241that matches various links, but also by settings like 242`Unmanaged=`, `RequiredForOnline=`, `RequiredFamilyForOnline=`; see 243[systemd.network(5)](http://www.freedesktop.org/software/systemd/man/systemd.socket.html). 244 245It is also possible to plug in additional checks for network state. For 246example, to delay `network-online.target` until some a specific host is 247reachable (the name can be resolved over DNS and the appropriate route has been 248established), the following simple service could be used: 249 250```ini 251[Unit] 252DefaultDependencies=no 253After=nss-lookup.target 254Before=network-online.target 255 256[Service] 257ExecStart=sh -c 'while ! ping -c 1 example.com; do sleep 1; done' 258 259[Install] 260WantedBy=network-online.target 261``` 262