manbytesgnu_site

Source files for manbytesgnu.org
git clone git://holbrook.no/manbytesgnu_site.git
Info | Log | Files | Refs

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.