20210609_iup.rst (5562B)
1 Homemade internet state monitor 2 ############################### 3 4 :date: 2021-07-01 13:59 5 :category: Hygiene 6 :author: Louis Holbrook 7 :tags: bash,systemd,network,i3wm,tmpfs,openvpn 8 :slug: internet-up-monitor 9 :summary: A small script to detect internet status 10 :lang: en 11 :status: published 12 13 14 I use `i3wm <https://i3wm.org>`_. I use it because it has a very low resource footprint, it has great documentation, and it's simple to configure. 15 16 Complementing *i3wm* is the *i3status* status provider to the *i3bar*. It provides a good suite of preset components for things like temperatur measurement, disk capacity. It also provides a couple of generic ones, namely "output the contents of a file" or "yes if file exists, no if not." 17 18 19 It's not you, it's me? 20 ====================== 21 22 .. WARNING:: 23 24 **Always use a VPN! Always!!** 25 26 27 Now, I *always* use VPN *no matter what*, and I configure network manually. That is, I do not use a network manager. For this reason, when network applications start misbehaving, it's sometimes hard to tell whether it is because the host is gone, the local network is flaky, the internet route is flaky, or simply that the connection is gone for good. 28 29 Evidently, it would be practical to have **an item in the status bar telling me whether I have access to internet right now or not**. 30 31 The "yes if file exists, no if not" option seems to be the right one to go for. Basically, we need to stick an empty file in a runtime file store whenever we detect that internet is available. 32 33 34 Ping, rinse, repeat 35 =================== 36 37 There's not much trickery involved here. The check is a ping to a remote location every now and then. 38 39 Some caveats to cover to grant it some minimum of intelligence: 40 41 - We need a few alternative destinations for the ping, that can take over if others happen to be down or take too long to repond. 42 43 - To make the script useful for general purpose use, we'd also want to be able to supply a custom list of hosts to ping. 44 45 - We also want to make sure that when the script is interrupted, it deletes the internet indicator file. That way, when it stops running, the internet indicator will be frozen in the "no" state. 46 47 - Lastly, it can be useful to log to syslog every time the state of the internet connection (or the script itself) changes. 48 49 That can translate to a shell script like this; 50 51 .. include:: code/iup/iup.sh 52 :code: bash 53 54 Since we'll want this to run when network interfaces allegedly are up, it makes sense to link it to systemd and the network target: 55 56 .. include:: code/iup/iup.service 57 :code: ini 58 59 Stick this in :code:`~/.config/systemd/user/iup.service` and enable and start the service: 60 61 .. code-block:: bash 62 63 $ systemctl --user enable iup.service 64 $ systemctl --user start iup.service 65 66 67 Checking what status our status is in 68 ===================================== 69 70 Now, in the i3status configuration, assuming that your system uid is 1000 [1]_, add: 71 72 .. code-block:: code 73 74 order += "run_watch INET" 75 76 kj 77 78 run_watch INET { 79 pidfile = "/run/user/1000/probe_up" 80 } 81 82 To reload the config on the fly, press :code:`mod+r` (that's :code:`ctrl+r` on mine). The result should be a new item in your bar showing :code:`INET: yes` (most likely yes, anyway, since you're currently reading this). 83 84 85 Safety first, eh ... second 86 =========================== 87 88 .. WARNING:: 89 90 **Did I mention that you should always use a VPN?** 91 92 93 The same :code:`run_watch` trick can be used for VPN. 94 95 I use :code:`openvpn`, and it defines a flag :code:`--writepid`. If you pass a file path to this parameter, either through the :code:`writepid` config directiry or on the :code:`--writepid` flag on the command line, it will write the openvpn pid to that file, and similarly remove it when the openvpn service ends. 96 97 However, this raises another issue. Namely the fact that a location is needed for openvpn to write the file to, for which it also has access. 98 99 If we want to use the :code:`/run` directory again, now we also has to make sure that this directory exists. 100 101 102 Got the runs? 103 ------------- 104 105 This is exactly what :code:`systemd-tmpfiles` is for. You can add files to :code:`/etc/tmpfiles.d` which describe what kind of temporary files or directories to add [2]_. 106 107 Create a file :code:`/etc/tmpfiles.d/openvpn.conf` and add a single line to it: 108 109 .. code-block:: code 110 111 d /run/openvpn 0755 openvpn openvpn 112 113 This will ensure that the folder is created at startup. 114 115 Now, to create one right away for the current session, run :code:`systemd-tmpfiles --create`. 116 117 Now we have everything we need to add the VPN status to *i3status* aswell. Provided that we chose :code:`/run/openvpn/openvpn.pid` as our argument to :code:`openvpn --writepid`, the setup is more or less the same as before: 118 119 120 .. code-block:: code 121 122 order += "run_watch VPN" 123 124 kj 125 126 run_watch VPN { 127 pidfile = "/run/openvpn/openvpn.pid" 128 } 129 130 131 .. 132 133 .. [1] The :code:`/run/user/$UID` folder will be created on system startup, and will be writable by that user. It provides a tmpfs storage location for processes that run in early stages of boot, before the entire filesystem tree (which may include :code:`/var/run` because :code:`/var` may be on a separate partition) has been mounted. More in that here: `<https://lwn.net/Articles/436012/>`_ 134 135 136 .. 137 138 .. [2] This service has an impressive amount of flexibility, which you can inspect yourself by visiting the :code:`tmpfiles.d` (and :code:`systemd-tmpfiles`) manpage.