<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Max Mehl (System administration)</title>
    <link>https://mehl.mx/tags/systemadministration/</link>
    <description>Recent content in SystemAdministration on Max Mehl</description>
    <generator>Hugo</generator>
    <language>en-GB</language>
    <lastBuildDate>Thu, 07 Nov 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mehl.mx/tags/systemadministration/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>INWX DNS Recordmaster - Manage your DNS nameserver records via files in Git</title>
      <link>https://mehl.mx/blog/2024/inwx-dns-recordmaster-manage-your-dns-nameserver-records-via-files-in-git/</link>
      <pubDate>Thu, 07 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://mehl.mx/blog/2024/inwx-dns-recordmaster-manage-your-dns-nameserver-records-via-files-in-git/</guid>
      <description>&lt;p&gt;I own and manage 30+ domains at &lt;a href=&#34;https://www.inwx.com/&#34;&gt;INWX&lt;/a&gt;, a large and professional domain registrar. Although INWX has a somewhat decent web interface, it became a burden for me to keep an overview of each domain&amp;rsquo;s sometimes dozens of records. Especially when e.g. changing an IP address for more than one domain, it caused multiple error-prone clicks and copy/pastes that couldn&amp;rsquo;t be reverted in the worst case. This is why I created &lt;a href=&#34;https://github.com/mxmehl/inwx-dns-recordmaster&#34;&gt;&lt;strong&gt;INWX DNS Recordmaster&lt;/strong&gt;&lt;/a&gt; which I will shortly present here.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I own and manage 30+ domains at &lt;a href=&#34;https://www.inwx.com/&#34;&gt;INWX&lt;/a&gt;, a large and professional domain registrar. Although INWX has a somewhat decent web interface, it became a burden for me to keep an overview of each domain&amp;rsquo;s sometimes dozens of records. Especially when e.g. changing an IP address for more than one domain, it caused multiple error-prone clicks and copy/pastes that couldn&amp;rsquo;t be reverted in the worst case. This is why I created &lt;a href=&#34;https://github.com/mxmehl/inwx-dns-recordmaster&#34;&gt;&lt;strong&gt;INWX DNS Recordmaster&lt;/strong&gt;&lt;/a&gt; which I will shortly present here.&lt;/p&gt;&#xA;&lt;p&gt;If you are an INWX customer, you can use this tool to manage all your DNS records in YAML files. Ideally, you will store these files in a Git repository which you can use to track changes and roll back in case of a mistake. Having one file per domain provides you a number of further advantages:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You can easily copy/paste records from other domains, e.g. for &lt;code&gt;SPF&lt;/code&gt;, &lt;code&gt;DKIM&lt;/code&gt; or &lt;code&gt;NS&lt;/code&gt; records&lt;/li&gt;&#xA;&lt;li&gt;Overall search/replace of certain values becomes much easier, e.g. of IP addresses&lt;/li&gt;&#xA;&lt;li&gt;You can prepare larger changes offline and can synchronise once you feel it&amp;rsquo;s done&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;INWX DNS Recordmaster takes care of making the required changes of the live records so that it matches the local state. This is done via the INWX API, ensuring that the amount of API calls is minimal.&lt;/p&gt;&#xA;&lt;p&gt;This even allows you to set up a pipeline that takes care of the synchronisation&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wait-there-is-more&#34;&gt;Wait, there is more&lt;/h2&gt;&#xA;&lt;p&gt;As written above, I already had a large stack of domains that I previously managed via the web interface. This is why some additional convenience features found their way into the tool.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You can convert all records of an existing and already configured domain at INWX into the file format. This made onboarding my 30+ domains a matter of a few minutes.&lt;/li&gt;&#xA;&lt;li&gt;On a global or per-domain level, you can ignore certain record types. For example, if you don&amp;rsquo;t want to touch any &lt;code&gt;NS&lt;/code&gt; records, you can configure that. By default, &lt;code&gt;SOA&lt;/code&gt; records are ignored. You may even ignore all live records that don&amp;rsquo;t exist in your local configuration.&lt;/li&gt;&#xA;&lt;li&gt;Of course, you can make a dry run to see which effects your configuration will have in practice.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Did I miss something to make it more productive for you? Let me know!&lt;/p&gt;&#xA;&lt;h2 id=&#34;install-use-contribute&#34;&gt;Install, use, contribute&lt;/h2&gt;&#xA;&lt;p&gt;You are welcome to &lt;a href=&#34;https://github.com/mxmehl/inwx-dns-recordmaster?tab=readme-ov-file#install&#34;&gt;install this tool&lt;/a&gt;, it&amp;rsquo;s Free and Open Source Software after all. All you need is Python installed.&lt;/p&gt;&#xA;&lt;p&gt;One of the tool&amp;rsquo;s users is the &lt;a href=&#34;https://openrailassociation.org&#34;&gt;OpenRail Association&lt;/a&gt; which manages some of its domains with this program and &lt;a href=&#34;https://github.com/OpenRailAssociation/openrail-dns&#34;&gt;published its configuration&lt;/a&gt;. This is a prime example of how organisation can make the management of records transparent and easy to change at least internally, if not even externally.&lt;/p&gt;&#xA;&lt;p&gt;While the tool is not perfect, it already is a huge gain for efficiency and stability of my IT operations, and it already proves its capabilities for other users. To reach the remaining 20% to perfection (that will take 80% of the time, as always), you are most welcome to add issues with enhancement proposals, and if possible, also pull requests.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;For example, see the &lt;a href=&#34;https://github.com/OpenRailAssociation/openrail-dns/blob/main/.github/workflows/sync-records.yaml&#34;&gt;workflow file of the OpenRail Association&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Seafile Mirror - Simple automatic backup of your Seafile libraries</title>
      <link>https://mehl.mx/blog/2023/seafile-mirror-simple-automatic-backup-of-your-seafile-libraries/</link>
      <pubDate>Fri, 22 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://mehl.mx/blog/2023/seafile-mirror-simple-automatic-backup-of-your-seafile-libraries/</guid>
      <description>&lt;p&gt;I have been using &lt;a href=&#34;https://www.seafile.com/&#34;&gt;Seafile&lt;/a&gt; for years to host and&#xA;synchronise files on my own server. It&amp;rsquo;s fast and reliable, especially when&#xA;dealing with a large number and size of files. But making reliable backups of&#xA;all its files isn&amp;rsquo;t so trivial. This is because the files are stored in a layout&#xA;similar to bare Git repositories, and Seafile&amp;rsquo;s headless tool, seafile-cli,&#xA;is&amp;hellip; suboptimal. So I created what started out as a wrapper for it and ended up&#xA;as a full-blown tool for automatically synchronising your libraries to a backup&#xA;location: &lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror&#34;&gt;&lt;strong&gt;Seafile Mirror&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;I have been using &lt;a href=&#34;https://www.seafile.com/&#34;&gt;Seafile&lt;/a&gt; for years to host and&#xA;synchronise files on my own server. It&amp;rsquo;s fast and reliable, especially when&#xA;dealing with a large number and size of files. But making reliable backups of&#xA;all its files isn&amp;rsquo;t so trivial. This is because the files are stored in a layout&#xA;similar to bare Git repositories, and Seafile&amp;rsquo;s headless tool, seafile-cli,&#xA;is&amp;hellip; suboptimal. So I created what started out as a wrapper for it and ended up&#xA;as a full-blown tool for automatically synchronising your libraries to a backup&#xA;location: &lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror&#34;&gt;&lt;strong&gt;Seafile Mirror&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-requirements&#34;&gt;My requirements&lt;/h2&gt;&#xA;&lt;p&gt;Of course, you could just take snapshots of the whole server, or copy the raw&#xA;Seafile data files and import them into a newly created Seafile instance as a&#xA;disaster recovery, but I want to be able to &lt;strong&gt;directly access the current&#xA;state of the files&lt;/strong&gt; whenever I need them in case of an emergency.&lt;/p&gt;&#xA;&lt;p&gt;It was also important for me to have a &lt;strong&gt;snapshot&lt;/strong&gt;, not just another real-time&#xA;sync of a library. This is because I also want to have a backup in case I (or an&#xA;attacker) mess up a Seafile library. A real-time sync would immediately fetch&#xA;that failed state.&lt;/p&gt;&#xA;&lt;p&gt;I also want to take a snapshot at a &lt;strong&gt;configurable interval&lt;/strong&gt;. Some libraries&#xA;should be synchronised more often than others. For example, my picture albums do&#xA;not change as often as my miscellaneous documents, but they use at least 20&#xA;times the disk space and therefore network traffic when running a full sync.&lt;/p&gt;&#xA;&lt;p&gt;Also, the backup service must have &lt;strong&gt;read-only access&lt;/strong&gt; to the files.&lt;/p&gt;&#xA;&lt;p&gt;A version controlled backup of the backup (i.e. the plain files) wasn&amp;rsquo;t in&#xA;scope. I handle this separately by backing up my backup location, which also&#xA;contains similar backups of other services and machines. For this reason, my&#xA;current solution does not do incremental backups, even though this may be&#xA;relevant for other use cases.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problems&#34;&gt;The problems&lt;/h2&gt;&#xA;&lt;p&gt;Actually, &lt;a href=&#34;https://help.seafile.com/syncing_client/linux-cli/&#34;&gt;seafile-cli&lt;/a&gt;&#xA;should have been everything you&amp;rsquo;d need to fulfill the requirements. But no. It&#xA;turned out that this tool has a number of fundamental issues:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You can make the host the tool is running on a sync peer. However, it easily&#xA;leads to sync errors if the user just has read-only permissions to the&#xA;library.&lt;/li&gt;&#xA;&lt;li&gt;You can also download a library but then again it may lead to strange sync&#xA;errors.&lt;/li&gt;&#xA;&lt;li&gt;It requires a running daemon which crashes irregularly during larger sync&#xA;tasks or has other issues.&lt;/li&gt;&#xA;&lt;li&gt;Download/sync intervals cannot be set manually.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;the-solution&#34;&gt;The solution&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror&#34;&gt;seafile-mirror&lt;/a&gt; takes care of all&#xA;these stumbling blocks:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;It downloads/syncs defined libraries in customisable intervals&lt;/li&gt;&#xA;&lt;li&gt;It de-syncs libaries immediately after they have been downloaded to avoid sync&#xA;errors&lt;/li&gt;&#xA;&lt;li&gt;You can force-re-sync a library even if its re-sync interval hasn&amp;rsquo;t reached&#xA;yet&lt;/li&gt;&#xA;&lt;li&gt;Extensive informative and error logging is provided&lt;/li&gt;&#xA;&lt;li&gt;Of course created with automation in mind so you can run it in cronjobs or&#xA;systemd triggers&lt;/li&gt;&#xA;&lt;li&gt;And as explained, it deals with the numerous caveats of &lt;code&gt;seaf-cli&lt;/code&gt; and Seafile&#xA;in general&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Full installation and usage documentation can be found in the project&#xA;repository. Installation is as simple as running &lt;code&gt;pip3 install seafile-mirror&lt;/code&gt;,&#xA;and a sample configuration is provided.&lt;/p&gt;&#xA;&lt;p&gt;In my setup, I run this application on a headless server with systemd under a&#xA;separate user account. Therefore the systemd service needs to be set up first.&#xA;This is also covered in the tool&amp;rsquo;s documentation. And as an Ansible power user,&#xA;I also provide an &lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror-ansible&#34;&gt;Ansible&#xA;role&lt;/a&gt; that does all the setup&#xA;and configuration.&lt;/p&gt;&#xA;&lt;h2 id=&#34;possible-next-steps&#34;&gt;Possible next steps&lt;/h2&gt;&#xA;&lt;p&gt;The tool has been running every day since a couple of months without any issues.&#xA;However, I could imagine a few more features to be helpful for more people:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Support of login tokens: Currently, only user/password auth is supported which&#xA;is fine for my use-case as it&amp;rsquo;s just a read-only user. This wouldn&amp;rsquo;t be hard&#xA;to fix either, seafile-cli supports it (at least in theory).&#xA;(&lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror/issues/2&#34;&gt;#2&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;li&gt;Support of encrypted libraries: Shouldn&amp;rsquo;t be a big issue, it would require&#xA;passing the password to the underlying seafile-cli command.&#xA;(&lt;a href=&#34;https://src.mehl.mx/mxmehl/seafile-mirror/issues/3&#34;&gt;#3&lt;/a&gt;)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If you have encountered problems or would like to point out the need for&#xA;specific features, please feel free to contact me or comment on the Mastodon&#xA;post. I&amp;rsquo;d also love to hear if you&amp;rsquo;ve become a happy user of the tool 😊.&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Docker2Caddy - An automatic Reverse Proxy for Docker containers</title>
      <link>https://mehl.mx/blog/2022/docker2caddy-an-automatic-reverse-proxy-for-docker-containers/</link>
      <pubDate>Mon, 25 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://mehl.mx/blog/2022/docker2caddy-an-automatic-reverse-proxy-for-docker-containers/</guid>
      <description>&lt;p&gt;So you have a number of Docker containers running web services which you would&#xA;like to expose to the outside? Well, you probably will at least have considered&#xA;a reverse proxy already. Doing this manually for one, two or even five&#xA;containers may be feasible, but everything above that will be a PITA for sure.&#xA;At the &lt;a href=&#34;https://fsfe.org&#34;&gt;FSFE&lt;/a&gt; we ran into the same issue with our &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/container-server/&#34;&gt;own&#xA;distributed container&#xA;infrastructure&lt;/a&gt; at&#xA;and crafted a neat solution that I would like to present to you in the next few&#xA;minutes.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;So you have a number of Docker containers running web services which you would&#xA;like to expose to the outside? Well, you probably will at least have considered&#xA;a reverse proxy already. Doing this manually for one, two or even five&#xA;containers may be feasible, but everything above that will be a PITA for sure.&#xA;At the &lt;a href=&#34;https://fsfe.org&#34;&gt;FSFE&lt;/a&gt; we ran into the same issue with our &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/container-server/&#34;&gt;own&#xA;distributed container&#xA;infrastructure&lt;/a&gt; at&#xA;and crafted a neat solution that I would like to present to you in the next few&#xA;minutes.&lt;/p&gt;&#xA;&lt;p&gt;The result is&#xA;&lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/docker2caddy/&#34;&gt;Docker2Caddy&lt;/a&gt; that&#xA;provides a workflow in which you can spin up new containers anytime (e.g. via a&#xA;CI) and the reverse proxy will just do the rest for you magically.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-assumptions&#34;&gt;The assumptions&lt;/h2&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s assume you want to go with reverse proxies to make your web services&#xA;accessible via ports 80 and 443. There are other possibilities, and in more&#xA;complex environments there may be already integrated solutions, but for this&#xA;article we&amp;rsquo;ll wade in a rather simple environment spun up with &lt;code&gt;docker-compose&lt;/code&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s also assume you care about security and go with a rootless installation of&#xA;Docker. So the daemon will run as an unprivileged user. That&amp;rsquo;s possible but much&#xA;more complex than the default rootful installation&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. Because of this, a few&#xA;other solutions will not work, we&amp;rsquo;ll check that later.&lt;/p&gt;&#xA;&lt;p&gt;Finally, each container shall at least have one separate domain assigned to it&#xA;for which you obviously want to have a valid certificate, e.g. by Let&amp;rsquo;s Encrypt.&lt;/p&gt;&#xA;&lt;p&gt;In the examples below, we have two containers running, each running a webserver&#xA;listening to port &lt;code&gt;8080&lt;/code&gt;. The first container shall be available via&#xA;&lt;code&gt;first.com&lt;/code&gt;, the second via &lt;code&gt;second.net&lt;/code&gt;. The latter shall also be available via&#xA;&lt;code&gt;www.second.net&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problems&#34;&gt;The problems&lt;/h2&gt;&#xA;&lt;p&gt;In the described scenario, there are a number of problem for automating the&#xA;configuration of the reverse proxy in order to direct a domain to the correct&#xA;container, starting with &lt;strong&gt;container discovery&lt;/strong&gt; to &lt;strong&gt;IPv6 routing&lt;/strong&gt; to&#xA;&lt;strong&gt;handling offline containers&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The reverse proxy has to be able to discover the currently running containers&#xA;and ideally monitor for changes regularly so that a newly created container with&#xA;a new domain is reachable within a short time without manual intervention.&lt;/p&gt;&#xA;&lt;p&gt;Before Docker2Caddy we have used&#xA;&lt;a href=&#34;https://github.com/nginx-proxy/nginx-proxy&#34;&gt;nginx-proxy&lt;/a&gt; combined with&#xA;&lt;a href=&#34;https://github.com/nginx-proxy/acme-companion&#34;&gt;acme-companion&lt;/a&gt; (formerly known&#xA;as &lt;em&gt;docker-letsencrypt-nginx-proxy-companion&lt;/em&gt;). These are Docker containers that&#xA;query all containers connected to the &lt;code&gt;bridge&lt;/code&gt; Docker network. For this to work,&#xA;the containers have to run with environment variables indicating the desired&#xA;domains and local ports that shall be proxied.&lt;/p&gt;&#xA;&lt;p&gt;In a rootless Docker setup this finally reaches its limits although discovery&#xA;still works. But already before that we did not like the fact that we had to&#xA;connect containers to the bridge network upon creation and therefore lost a bit&#xA;more isolation (which is dubious in Docker anyway).&lt;/p&gt;&#xA;&lt;p&gt;Now, with rootless, IPv6 was the turning point. Even in rootful Docker setups,&#xA;IPv6 – a 20+ years old, well defined standard protocol – is a pain in the butt.&#xA;But with rootless, the FSFE System Hackers team did not manage to get IPv6&#xA;working in containers to the degree that we needed. While IPv6 traffic reached&#xA;the &lt;code&gt;nginx-proxy&lt;/code&gt;, it was then treated as IPv4 traffic with the internal Docker&#xA;IP address. That bits you ultimately if you limit requests based on IP&#xA;addresses, e.g. for signups or payments. All traffic via IPv6 will be treated&#xA;as the same internal IPv4 address, therefore triggering the limits regularly.&lt;/p&gt;&#xA;&lt;p&gt;The easiest solution therefore is to use a reverse proxy running on the host&#xA;system, not as a Docker container with its severe limitations. While the first&#xA;intuition lead us to nginx, we decided to go with&#xA;&lt;a href=&#34;https://caddyserver.com/&#34;&gt;Caddy&lt;/a&gt;. The main advantages we saw are that a virtual&#xA;host in Caddy is very simple to configure and that TLS certificates are&#xA;generated and maintained automatically without extra dependencies like&#xA;&lt;code&gt;certbot&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In this setup, containers would need to open their webserver port to the host.&#xA;This “public” port has to be unique per host, but the internal port can stay the&#xA;same, e.g. port &lt;code&gt;1234&lt;/code&gt; could be mapped to port &lt;code&gt;8080&lt;/code&gt; inside the container. In&#xA;Caddy you would then configure the domain &lt;code&gt;first.org&lt;/code&gt; to forward to&#xA;&lt;code&gt;localhost:1234&lt;/code&gt;. A more or less identical second example container could then&#xA;expose the port &lt;code&gt;5678&lt;/code&gt; to the host, again listen on &lt;code&gt;8080&lt;/code&gt; internally, and Caddy&#xA;would redirect &lt;code&gt;second.net&lt;/code&gt; and &lt;code&gt;www.second.net&lt;/code&gt; to &lt;code&gt;localhost:5678&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;But how does Caddy know about the currently running containers and the ports via&#xA;which they want to receive traffic? And how can we handle containers that are&#xA;unavailable, for instance because they crashed or have been deleted for good?&#xA;Docker2Caddy to the rescue!&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-solution&#34;&gt;The solution&lt;/h2&gt;&#xA;&lt;p&gt;I already concluded that Caddy is a suitable reverse proxy for the outlined use&#xA;case. But in order to be care-free, the configuration has to be generated&#xA;automatically. For this to work, I wrote a rather simple Python application&#xA;called &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/docker2caddy&#34;&gt;Docker2Caddy&lt;/a&gt;&#xA;that is kept running in the background via a systemd service and writes proper&#xA;logs that are also rotated nicely.&lt;/p&gt;&#xA;&lt;p&gt;This is how it works internally: it queries (in a configurable interval) the&#xA;Docker daemon for running containers. For each container it looks for specific&#xA;labels (that are also configurable), by default &lt;code&gt;proxy.host&lt;/code&gt;, &lt;code&gt;proxy.host_alias&lt;/code&gt;&#xA;and &lt;code&gt;proxy.port&lt;/code&gt;. If one or multiple containers are found – in our case two –&#xA;one Caddy configuration file per container is created. This is based on a freely&#xA;configurable Jinja2 template. If the configuration changed, e.g. by a new host,&#xA;Caddy will be reloaded and will create a TLS certificate if needed.&lt;/p&gt;&#xA;&lt;p&gt;But what happens if a container is unavailable? In Docker2Caddy you can&#xA;configure a grace period. Until this is reached, the Caddy configuration for the&#xA;container in question is not removed but could forward to a local or remote&#xA;error page. Only afterwards, the configuration is removed, and Caddy reloaded&#xA;subsequently.&lt;/p&gt;&#xA;&lt;p&gt;So, what makes Docker2Caddy special? I am biased but see a number of points:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: fundamentally it&amp;rsquo;s a 188 pure lines of code Python script.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Configurability&lt;/strong&gt;: albeit it&amp;rsquo;s simplicity, it&amp;rsquo;s easy to configure for&#xA;various needs thanks to the templates and the support for rootless Docker&#xA;setups.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Adaptability&lt;/strong&gt;: it should be rather simple to make Docker2Caddy also work&#xA;for Podman, or even use different reverse proxies. Feel free to extend it&#xA;before I&amp;rsquo;ll do it myself someday ;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: while I did not perform before/after benchmarks, Caddy is&#xA;blazingly fast and will surely perform better on the host than in a limited&#xA;Docker container.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re facing the same challenges in your setup, please feel free to try it&#xA;out. Installation is quite simple and there&amp;rsquo;s even a &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/docker2caddy/src/branch/master/install.yml&#34;&gt;minimal Ansible&#xA;playbook&lt;/a&gt;.&#xA;If you have feedback, I appreciate reading it via comments on Mastodon (see&#xA;below), &lt;a href=&#34;https://mehl.mx/contact/&#34;&gt;email&lt;/a&gt;, or, if you have an FSFE account, as a new issue or&#xA;patch at the &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/docker2caddy&#34;&gt;main repo&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/minimal-docker&#34;&gt;This is&lt;/a&gt; how a&#xA;very minimal Docker service in the FSFE infrastructure looks like. For&#xA;Docker2Caddy, only the &lt;code&gt;docker-compose.yml&lt;/code&gt; file with its labels is&#xA;relevant.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re interested in setting this up via Ansible, I can recommend the&#xA;&lt;a href=&#34;https://github.com/konstruktoid/ansible-docker-rootless&#34;&gt;ansible-docker-rootless&lt;/a&gt;&#xA;role which we integrated in our full-blown&#xA;&lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/container-server/&#34;&gt;playbook&lt;/a&gt; for&#xA;the container servers.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>System Hackers meeting - Lyon edition</title>
      <link>https://mehl.mx/blog/2020/system-hackers-meeting-lyon-edition/</link>
      <pubDate>Tue, 31 Mar 2020 00:00:00 +0000</pubDate>
      <guid>https://mehl.mx/blog/2020/system-hackers-meeting-lyon-edition/</guid>
      <description>&lt;p&gt;For the 4th time, and less than 5 months after the last meeting, the&#xA;FSFE System Hackers met in person to coordinate their activities, work&#xA;on complex issues, and exchange know-how. This time, we chose yet&#xA;another town familiar to one of our team members as venue – Lyon in&#xA;France. What follows is a report of this gathering that happened&#xA;shortly before &lt;em&gt;#stayhome&lt;/em&gt; became the order of the day.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;For the 4th time, and less than 5 months after the last meeting, the&#xA;FSFE System Hackers met in person to coordinate their activities, work&#xA;on complex issues, and exchange know-how. This time, we chose yet&#xA;another town familiar to one of our team members as venue – Lyon in&#xA;France. What follows is a report of this gathering that happened&#xA;shortly before &lt;em&gt;#stayhome&lt;/em&gt; became the order of the day.&lt;/p&gt;&#xA;&lt;p&gt;For those who do not know this less visible but important team: The&#xA;System Hackers are responsible for the maintenance and development of a&#xA;&lt;a href=&#34;https://wiki.fsfe.org/TechDocs/Services&#34;&gt;large number of services&lt;/a&gt;.&#xA;From the fsfe.org website&amp;rsquo;s deployment to the mail servers and blogs,&#xA;from Git to internal services like DNS and monitoring, all these&#xA;services, virtual machines and physical servers are handled by &lt;a href=&#34;https://wiki.fsfe.org/Teams/System-Hackers/&#34;&gt;this&#xA;friendly group&lt;/a&gt; that is&#xA;always looking forward to welcoming new members.&lt;/p&gt;&#xA;&lt;p&gt;Interestingly, we have gathered in the same constellation as in the&#xA;&lt;a href=&#34;https://mehl.mx/blog/2019/the-3rd-fsfe-system-hackers-hackathon/&#34;&gt;hackathon&#xA;before&lt;/a&gt;,&#xA;so Albert, Florian, Francesco, Thomas, Vincent and me tackled large and&#xA;small challenges in the FSFE&amp;rsquo;s systems. But we have also used the time&#xA;to exchange knowledge about complex tasks and some interconnected&#xA;systems. The official part was conducted in the fascinating &lt;a href=&#34;https://web.archive.org/web/20200814122815/http://astech-fablab.fr/&#34;&gt;Astech&#xA;Fablab&lt;/a&gt;, but word has it that&#xA;&lt;a href=&#34;https://www.ninkasi.fr/&#34;&gt;Ninkasi&lt;/a&gt;, an excellent pub in Lyon, was the&#xA;actual epicentre of this year&amp;rsquo;s meeting.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sharing-is-caring&#34;&gt;Sharing is caring&lt;/h2&gt;&#xA;&lt;p&gt;Saturday morning after reviewing open tasks and setting our priorities,&#xA;we started to share more knowledge about our services to reduce&#xA;bottlenecks. For this, I drew a few diagrams to explain how we deploy&#xA;our Docker containers, how our community database interacts with the&#xA;mail and lists server, and how DNS works at the FSFE.&lt;/p&gt;&#xA;&lt;p&gt;To also help the non-present system hackers and “future generations”,&#xA;I&amp;rsquo;ve added this information to a &lt;a href=&#34;https://wiki.fsfe.org/TechDocs/Systems&#34;&gt;public wiki&#xA;page&lt;/a&gt;. This could also be the&#xA;starting point to transfer more internal knowledge to public pages to&#xA;make maintenance and onboarding easier.&lt;/p&gt;&#xA;&lt;h2 id=&#34;todo-done&#34;&gt;Todo? Done!&lt;/h2&gt;&#xA;&lt;p&gt;Afterwards, we focused on closing tasks that have been open for a longer&#xA;time:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The DNS has been a big issue for a long time. Over the past months&#xA;we&amp;rsquo;ve migrated the source for our nameserver entries from SVN to Git,&#xA;rewrote our deployment scripts, and eventually upgraded the two very&#xA;sensitive systems to Debian 10. During the meeting, we came closer to&#xA;perfection: all Bind configuration cleaned from old entries, uniformly&#xA;formatted, and now featuring SPF, DMARC and CAA records.&lt;/li&gt;&#xA;&lt;li&gt;For a better security monitoring of the 100+ mailing lists the FSFE&#xA;hosts, we&amp;rsquo;ve finalised the weekly automatic checks for sane and safe&#xA;settings, and a tool that helps to easily update the internal&#xA;documentation.&lt;/li&gt;&#xA;&lt;li&gt;Speaking of monitoring: we did lack proper monitoring of our 20+ hosts&#xA;for availability, disk usage, TLS certificates, service status and&#xA;more. While we tried for a longer time to get Prometheus and Grafana&#xA;doing what we need, we performed a 180° turn: now, there is a Icinga2&#xA;installation running that already monitors a few hosts and their&#xA;services – &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/monitoring&#34;&gt;deployed with&#xA;Ansible&lt;/a&gt;. In the&#xA;following weeks we will add more hosts and services to the watched&#xA;targets.&lt;/li&gt;&#xA;&lt;li&gt;We plan to migrate our user-unfriendly way to share files between&#xA;groups to Nextcloud, including using some more of the software&amp;rsquo;s&#xA;capabilities. During the weekend, we&amp;rsquo;ve tested the instance&#xA;thoroughly, and created some more LDAP groups that are automatically&#xA;transposed to groups in Nextcloud. In the same run, Albert shared some&#xA;more knowledge about LDAP with Vincent and me, so we get rid of more&#xA;bottlenecks.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Then, it was time to deal with other urgent issues:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Some of us worked on making our systems more resilient against DDoS&#xA;attacks. Over the Christmas season, we became a target of an attack.&#xA;The idea is to come up with solutions that are easy to deploy on all&#xA;our web services while keeping complexity low. We&amp;rsquo;ve tested some&#xA;approaches and will further work on coming up with solutions.&lt;/li&gt;&#xA;&lt;li&gt;Regarding webservers, we&amp;rsquo;ve updated the TLS configurations on various&#xA;services to the recommended settings, and also improved some other&#xA;settings while touching the configuration files.&lt;/li&gt;&#xA;&lt;li&gt;We intend to ease people encrypting their emails with GnuPG. That is&#xA;why we experimented with WKD/WKS and will work on setting up this&#xA;service. As it requires some interconnection with others services,&#xA;this will take us some more time unfortunately.&lt;/li&gt;&#xA;&lt;li&gt;On the maintenance side of things, we have upgraded all servers except&#xA;one to the latest Debian version, and also updated many of our Docker&#xA;images and containers to make use of the latest security and stability&#xA;improvements.&lt;/li&gt;&#xA;&lt;li&gt;The FSFE hosts a few third party services, and unfortunately they have&#xA;been running on unmaintained systems. That is why we set up a brand&#xA;new host for our &lt;a href=&#34;https://fsfla.org&#34;&gt;sister organisation in Latin&#xA;America&lt;/a&gt; so they can eventually migrate, and moved&#xA;the &lt;a href=&#34;https://fossmarks.org&#34;&gt;fossmarks.org&lt;/a&gt; website to our automatic&#xA;CI/CD setup via Drone/Docker.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;the-next-steps-and-developments&#34;&gt;The next steps and developments&lt;/h2&gt;&#xA;&lt;p&gt;As you can see, we completed and started to tackle a lot of issues&#xA;again, so it won&amp;rsquo;t become boring in our team any time soon. However,&#xA;although we should know better, we intend to “change a running system”!&lt;/p&gt;&#xA;&lt;p&gt;While the in-person meetings have been highly important and also fun,&#xA;we are in a state where knowledge and mutual trust are further&#xA;distributed between the members, the tasks separated more clearly and&#xA;the systems mostly well documented. So part of our feedback session was&#xA;the question whether these meetings in the 6-12 month rhythm are still&#xA;necessary.&lt;/p&gt;&#xA;&lt;p&gt;Yes, they are, but not more often than once a year. Instead, we would&#xA;like to try virtual meetings and sprints. Before a sprint session, we&#xA;would discuss all tasks (basically go through our internal Kan board),&#xA;plan the challenges, ask for input if necessary, and resolve blockers as&#xA;early as possible. Then, we would be prepared for a sprint day or&#xA;afternoon during which everyone can work on their tasks while being able&#xA;to directly contact other members. All that should happen over a video&#xA;conference to have a more personal atmosphere.&lt;/p&gt;&#xA;&lt;p&gt;For the analogue meetings, it was requested to also plan tasks and&#xA;priorities beforehand together, and focus on tasks that require more&#xA;people from the group. Also, we want to have more trainings and system&#xA;introductions like we&amp;rsquo;ve just had to reduce dependencies on single&#xA;persons.&lt;/p&gt;&#xA;&lt;p&gt;All in all, this gathering has been another successful meeting and will&#xA;set a corner stone for exciting new improvements for both the systems&#xA;and the team. Thanks to everyone who participated, and a big applause to&#xA;Vincent who organised the venue and the social activities!&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>The 3rd FSFE System Hackers hackathon</title>
      <link>https://mehl.mx/blog/2019/the-3rd-fsfe-system-hackers-hackathon/</link>
      <pubDate>Tue, 22 Oct 2019 00:00:00 +0000</pubDate>
      <guid>https://mehl.mx/blog/2019/the-3rd-fsfe-system-hackers-hackathon/</guid>
      <description>&lt;p&gt;On 10 and 11 October, the FSFE System Hackers met in person to tackle&#xA;problems and new features regarding the servers and services the FSFE&#xA;is running. The team consists of dedicated volunteers who ensure that&#xA;the community and staff can work effectively. The recent meeting built&#xA;on the great work of the past 2 years which have been shaped by large&#xA;personal and technical changes.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;On 10 and 11 October, the FSFE System Hackers met in person to tackle&#xA;problems and new features regarding the servers and services the FSFE&#xA;is running. The team consists of dedicated volunteers who ensure that&#xA;the community and staff can work effectively. The recent meeting built&#xA;on the great work of the past 2 years which have been shaped by large&#xA;personal and technical changes.&lt;/p&gt;&#xA;&lt;p&gt;The System Hackers are responsible for the maintenance and development&#xA;of a &lt;a href=&#34;https://wiki.fsfe.org/TechDocs/Services&#34;&gt;large number of&#xA;services&lt;/a&gt;. From the fsfe.org&#xA;website&amp;rsquo;s deployment to the mail servers and blogs, from Git to&#xA;internal services like DNS and monitoring, all these services, virtual&#xA;machines and physical servers are handled by &lt;a href=&#34;https://wiki.fsfe.org/Teams/System-Hackers/&#34;&gt;this friendly&#xA;group&lt;/a&gt; that is always&#xA;looking forward to welcoming new members.&lt;/p&gt;&#xA;&#xA;&lt;link rel=&#34;stylesheet&#34; href=&#34;https://mehl.mx/css/snap-gallery.css&#34; /&gt;&lt;figure &gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &lt;a href=&#34;#fig1&#34;&gt;&#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/system-servers.png&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;        &lt;figcaption&gt;Overview of the FSFE&amp;rsquo;s services and servers&lt;/figcaption&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;div class=&#34;snap-lightbox&#34; id=&#34;fig1&#34;&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close&#34;&gt;&lt;/a&gt;&#xA;        &lt;div class=&#34;snap-lightbox-inner&#34;&gt;&#xA;          &lt;img src=&#34;https://mehl.mx/img/blog/system-servers.png&#34;  /&gt;&#xA;          &lt;p&gt;Overview of the FSFE&amp;rsquo;s services and servers&#xA;          &lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close-button&#34;&gt;&lt;i class=&#34;snap-lightbox-x&#34;&gt;&lt;/i&gt;&lt;/a&gt;&#xA;      &lt;/div&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;So in October, six of us met in Cologne. Fittingly, according to a&#xA;saying in this region, if you do something for the third time, it&amp;rsquo;s&#xA;already tradition. So we accomplished this after successful meetings in&#xA;Berlin (April 2018) and Vienna (March 2019). And although it took place&#xA;on workdays, it&amp;rsquo;s been the meeting with the highest participation so&#xA;far!&lt;/p&gt;&#xA;&lt;h2 id=&#34;getting-things-done&#34;&gt;Getting. Things. Done!&lt;/h2&gt;&#xA;&lt;p&gt;After the first and second meeting were mostly about getting an&#xA;overview of historically grown and sparsely documented infrastructure&#xA;and bringing it into a stable state, we were able to deal with a few&#xA;more general topics this time. At the same time, we exchanged our&#xA;knowledge with newly joined team members. Please find the areas we&#xA;worked on below:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Florian migrated the FSFE Blogs to a new server and thereby also&#xA;updated the underlying Wordpress to the latest version. This has been&#xA;a major blocker for several other tasks and our largest security risk.&#xA;There are still a few things left to do, e.g. creating a theme in line&#xA;with the FSFE design and some announcement to the community. However,&#xA;the most complicated part is done!&lt;/li&gt;&#xA;&lt;li&gt;Altogether, we upgraded a lot of machines to Debian 10, just after we lifted most&#xA;servers to Debian 9 in March. Some are still missing, but since the&#xA;migration is rather painless, we can do that during the next months.&lt;/li&gt;&#xA;&lt;li&gt;We confirmed that the new decentralised backup system setup by myself&#xA;and based on Borg works fine. This gives us more confidence in our&#xA;infrastructure.&lt;/li&gt;&#xA;&lt;li&gt;Thanks to Florian and Albert, we finally got rid of the last 2&#xA;services that were not using Let&amp;rsquo;s Encrypt&amp;rsquo;s self-renewing&#xA;certificates.&lt;/li&gt;&#xA;&lt;li&gt;Vincent and Francesco took care of finishing the migration of all our Docker containers&#xA;to use the Docker-in-Docker deployment instead of the hacky Ansible&#xA;playbooks we used initially. This has a few security advantages and&#xA;enables the next developments for a more resilient Docker&#xA;infrastructure.&lt;/li&gt;&#xA;&lt;li&gt;At the moment, all our Docker containers run on one single virtual&#xA;machine. Although this runs on a Proxmox/Ceph cluster, it&amp;rsquo;s obviously&#xA;a single point of failure. However, for a distribution on multiple&#xA;servers we lack the hardware resources. Nonetheless, we already have&#xA;concrete plans how to make the Docker setup more resilient as soon as&#xA;we have more hardware available. Vincent documented this on &lt;a href=&#34;https://wiki.fsfe.org/TechDocs/Docker/docker-machine&#34;&gt;a wiki&#xA;page&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;On the human side, we made sure that all of us know what&amp;rsquo;s on the&#xA;plate for the next weeks and months. We have quite a few open issues&#xA;collected in our Kanban board, and we quickly went through all of them&#xA;to sketch the possible next steps and distribute responsibilities.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;started-projects-in-the-making&#34;&gt;Started projects in the making&lt;/h2&gt;&#xA;&lt;p&gt;Two days are quite some time and we worked hard to use them as&#xA;effectively as possible, so some tasks have been started but could not&#xA;be completed – partly because we just did no have enough time, partly&#xA;because they require more coordination and in-depth discussion:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;As follow-up on a few unpleasant surprises with Mailman&amp;rsquo;s default&#xA;values, we figured that it is important to have an automatic overview&#xA;of the most sensible settings of the 127 (!) mailing lists we host.&#xA;Vincent started to work on a way to extract this information in a&#xA;human- and machine-readable format and merge/compare it with the more&#xA;verbose documentation on the mailing lists we have internally.&lt;/li&gt;&#xA;&lt;li&gt;Francesco tackled a different weak point we have: monitoring. We lack&#xA;a tool that informs us immediately about problems in our&#xA;infrastructure, e.g. defunct core services, full disk drives or&#xA;expired certificates. Since this is not trivial at all, it requires&#xA;some more time.&lt;/li&gt;&#xA;&lt;li&gt;Thomas, maintainer of the FSFE wiki, researched on a way to better organise and distribute the SSH&#xA;accesses in our team. Right now, we have no comfortable way to add or&#xA;remove SSH keys on our more than 20 machines. His idea is to use an&#xA;Ansible playbook to manage these, and thereby also create a shared&#xA;Ansible inventory which can be used as a submodule for the other&#xA;playbooks we use in the team so we don&amp;rsquo;t have to maintain all of them&#xA;individually if a machine is added, changed or removed.&lt;/li&gt;&#xA;&lt;li&gt;One of the most ancient physical machines we still run is hosting the&#xA;SVN service which is only used by one service now: DNS. We started to work&#xA;on migrating that over to Git and simultaneously improving the&#xA;error-checking of the DNS configuration. Albert and I will continue&#xA;with that gradually.&lt;/li&gt;&#xA;&lt;li&gt;Not on the system hackers meeting itself but two days later, Björn,&#xA;Albert and I worked on getting a Nextcloud instance running. Caused by&#xA;our rather special LDAP setup, we had to debug a lot of strange&#xA;behaviour but finally figured everything out. Now, the last missing&#xA;blocker is some user/permission setting within our LDAP. As soon as&#xA;this is finished, we can shut down one more historically grown,&#xA;customised-hacked and user-unfriendly service.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Overall, the perspective for the System Hackers is better than ever. We&#xA;are a growing team carried by motivated and skilled volunteers with a&#xA;shared vision of how the systems should develop. At the same time, we&#xA;have a lot of public and internal documentation available to make it&#xA;easy for new people to join us.&lt;/p&gt;&#xA;&lt;p&gt;I would like to thank Albert, Florian, Francesco, Thomas and Vincent for&#xA;their participation in this meeting, and them and all other System&#xA;Hackers for their dedication to keep the FSFE running!&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>FSFE Planet has been refurbished</title>
      <link>https://mehl.mx/blog/2019/fsfe-planet-has-been-refurbished/</link>
      <pubDate>Mon, 11 Feb 2019 10:33:11 +0000</pubDate>
      <guid>https://mehl.mx/blog/2019/fsfe-planet-has-been-refurbished/</guid>
      <description>&lt;p&gt;If you are reading these lines, you are already accessing the brand-new planet of the FSFE. While Björn, Coordinator of Team Germany, has largely improved the design in late 2017, we tackled many underlying issues this time.&lt;/p&gt;&#xA;&lt;p&gt;So what has changed under the hood?&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;If you are reading these lines, you are already accessing the brand-new planet of the FSFE. While Björn, Coordinator of Team Germany, has largely improved the design in late 2017, we tackled many underlying issues this time.&lt;/p&gt;&#xA;&lt;p&gt;So what has changed under the hood?&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The whole system runs in a Docker container now, with all code accessible on &lt;a href=&#34;https://git.fsfe.org/fsfe-system-hackers/fsfe-planet&#34;&gt;our Git&lt;/a&gt;. Yes, Docker has drawbacks, but in this case it eases maintenance for our volunteers and makes contributions to design and code very simple.&lt;/li&gt;&#xA;&lt;li&gt;The old planet ran on a very old Debian server which had issues with modern TLS versions. This basically erased a few blogs from the planet whose webservers do not support older encryption standards.&lt;/li&gt;&#xA;&lt;li&gt;The design has been improved once more. It now more closely aligns to the design of our main page &lt;a href=&#34;https://fsfe.org&#34;&gt;fsfe.org&lt;/a&gt; and feels more natively to use and browse.&lt;/li&gt;&#xA;&lt;li&gt;Many blogs which were not accessible any more have been removed, and those which redirected to other URLs have been updated accordingly.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;So with the migration to the new system you will probably find a few new blogs and unread posts in your RSS feeds now. So please do not be confused about it but look forward to even more useful and interesting bits from the FSFE community!&lt;/p&gt;&#xA;&lt;p&gt;On this occasion I would like to thank Michael and Vincent for their contributions to the code, and the useful feedback from various people in the FSFE’s community. If you have ideas how to further improve our planet, please open an issue in the Git repository or &lt;a href=&#34;https://fsfe.org/about/contact/&#34;&gt;write an email to us&lt;/a&gt;.&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>splitDL – Downloading huge files from slow and unstable internet connections</title>
      <link>https://mehl.mx/blog/2015/splitdl-downloading-huge-files-from-slow-and-unstable-internet-connections/</link>
      <pubDate>Fri, 26 Jun 2015 15:59:03 +0000</pubDate>
      <guid>https://mehl.mx/blog/2015/splitdl-downloading-huge-files-from-slow-and-unstable-internet-connections/</guid>
      <description>&lt;p&gt;Imagine you want install GNU/Linux but your bandwidth won’t let you…&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;tl;dr: I wrote a rather small Bash script which splits huge files into several smaller ones and downloads them. To ensure the integrity, every small files is being checked for its hashsum and file size.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;That’s the problem I was facing in the past days. In the school I’m working at (&lt;a href=&#34;http://www.tareo-tz.org/mit/&#34;&gt;Moshi Institute of Technology&lt;/a&gt;, MIT) I set up a GNU/Linux server to provide services like file sharing, website design (on local servers to avoid the slow internet) and central backups. The ongoing plan is the setup of 5-10 (and later more) new computers with a GNU/Linux OS in contrast to the ancient and non-free WindowsXP installations – project „Linux Classroom“ is officially born.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Imagine you want install GNU/Linux but your bandwidth won’t let you…&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;tl;dr: I wrote a rather small Bash script which splits huge files into several smaller ones and downloads them. To ensure the integrity, every small files is being checked for its hashsum and file size.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;That’s the problem I was facing in the past days. In the school I’m working at (&lt;a href=&#34;http://www.tareo-tz.org/mit/&#34;&gt;Moshi Institute of Technology&lt;/a&gt;, MIT) I set up a GNU/Linux server to provide services like file sharing, website design (on local servers to avoid the slow internet) and central backups. The ongoing plan is the setup of 5-10 (and later more) new computers with a GNU/Linux OS in contrast to the ancient and non-free WindowsXP installations – project „Linux Classroom“ is officially born.&lt;/p&gt;&#xA;&lt;p&gt;But to install an operating system on a computer you need an installation medium. In the school a lot of (dubious) WindowsXP installation CD-ROMs are flying around but no current GNU/Linux. In the first world you would just download &lt;a href=&#34;https://en.wikipedia.org/wiki/ISO_image&#34;&gt;an .iso file&lt;/a&gt; and ~10 minutes later you could start installing it on your computer.&lt;/p&gt;&#xA;&lt;p&gt;But not here in Tanzania. With download rates of average 10kb/s it needs a hell of a time to download only one image file (not to mention the costs for the internet usage, ~1-3$ per 1GB). And that’s not all: Periodical power cuts cancel ongoing downloads abruptly. Of course you can restart a download but the large file may be already damaged and you loose even more time.&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-solution--splitdl&#34;&gt;My solution – splitDL&lt;/h2&gt;&#xA;&lt;p&gt;To circumvent this drawback I coded a rather small Bash program called &lt;a href=&#34;http://src.mehl.mx/mxmehl/split-dl&#34;&gt;&lt;strong&gt;splitDL&lt;/strong&gt;&lt;/a&gt;. With this helper script, one is able to split a huge file into smaller pieces. If during the download the power cuts off and damages the file, one just has to re-download this single small file instead of the huge complete file. To detect whether a small file is unharmed the script creates hashsums of the original huge and the several small files. The script also supports continuation of the download thanks to the great default built-in application &lt;a href=&#34;https://en.wikipedia.org/wiki/Wget&#34;&gt;wget&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;You might now think „BitTorrent (or any other program) is also able to do the same, if not more!“. Yes, but this requires a) the installation of another program and b) a download source which supports this protocol. On the contrary &lt;strong&gt;splitDL&lt;/strong&gt; can handle every HTTP, HTTPS or FTP download.&lt;/p&gt;&#xA;&lt;p&gt;The downside in the current state is that &lt;strong&gt;splitDL&lt;/strong&gt; requires shell access to the server where the file is saved to be able to split the file and create the necessary hashsums. So in my current situation I use my own virtual server in Germany on which I download the wanted file with high-speed and then use &lt;strong&gt;splitDL&lt;/strong&gt; to prepare the file for the slow download from my server to the Tanzanian school.&lt;/p&gt;&#xA;&lt;p&gt;The project is of course still in an ongoing phase and only tested in my own environment. Please feel free to have a look at it and &lt;a href=&#34;http://src.mehl.mx/mxmehl/split-dl&#34;&gt;download it via my Git instance&lt;/a&gt;. I’m always looking forward to feedback. The application is licensed under GPLv3 or later.&lt;/p&gt;&#xA;&lt;h2 id=&#34;some-examples&#34;&gt;Some examples&lt;/h2&gt;&#xA;&lt;h3 id=&#34;server-side&#34;&gt;Server-side&lt;/h3&gt;&#xA;&lt;p&gt;Split the file &lt;em&gt;debian.iso&lt;/em&gt; into smaller parts with the default options (MD5 hashsum, 10MB size)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;split-dl.sh -m server -f debian.iso&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Split the file but use the SHA1 hashsum and split the file into pieces with 50MB.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;split-dl.sh -m server -f debian.iso -c sha1sum -s 50M&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After one of the commands, a new folder called &lt;em&gt;dl-debian.iso/&lt;/em&gt; will be created. There, the splitted files and a document containing the hashsums and file sizes are located. You just have to move the folder to a web-accessible location on your server.&lt;/p&gt;&#xA;&lt;h3 id=&#34;client-side&#34;&gt;Client-side&lt;/h3&gt;&#xA;&lt;p&gt;Download the splitted files with the default options.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;split-dl.sh -m client -f http://server.tld/dl-debian.iso/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Download the splitted files but use SHA1 hashsum (has to be the same than what was used on the creation process) and override the wget options (default: &lt;em&gt;-nv –show-progress&lt;/em&gt;).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;split-dl.sh -m client -f http://server.tld/dl-debian.iso/ -c sha1sum -w --limit-date&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;100k&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;current-bugsdrawbacks&#34;&gt;Current bugs/drawbacks&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Currently only single files are possible to split. This will be fixed soon.&lt;/li&gt;&#xA;&lt;li&gt;Currently the script only works with files in the current directory. This is also only a matter of some lines of code.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>I love Taskwarrior, therefore I love Free Software</title>
      <link>https://mehl.mx/blog/2015/i-love-taskwarrior-therefore-i-love-free-software/</link>
      <pubDate>Sat, 14 Feb 2015 12:05:42 +0000</pubDate>
      <guid>https://mehl.mx/blog/2015/i-love-taskwarrior-therefore-i-love-free-software/</guid>
      <description>&lt;p&gt;“&lt;em&gt;It’s Valentine’s day and you’re writing a blog post? Are you nuts?&lt;/em&gt;” you might ask. Well, but it’s not only Valentine’s day but also &lt;a href=&#34;http://ilovefs.org&#34;&gt;I love Free Software&lt;/a&gt; day. This day is proclaimed every year on February 14 by the Free Software Foundation Europe to thank all developers and contributors of Free Software (software you can use for any purpose, which source code you or others can analyze, which can be modified and distributed).&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;“&lt;em&gt;It’s Valentine’s day and you’re writing a blog post? Are you nuts?&lt;/em&gt;” you might ask. Well, but it’s not only Valentine’s day but also &lt;a href=&#34;http://ilovefs.org&#34;&gt;I love Free Software&lt;/a&gt; day. This day is proclaimed every year on February 14 by the Free Software Foundation Europe to thank all developers and contributors of Free Software (software you can use for any purpose, which source code you or others can analyze, which can be modified and distributed).&lt;/p&gt;&#xA;&#xA;&lt;link rel=&#34;stylesheet&#34; href=&#34;https://mehl.mx/css/snap-gallery.css&#34; /&gt;&lt;figure class=&#34;sm pull-right&#34;&gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &lt;a href=&#34;#fig1&#34;&gt;&#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-heart-px.png&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;div class=&#34;snap-lightbox&#34; id=&#34;fig1&#34;&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close&#34;&gt;&lt;/a&gt;&#xA;        &lt;div class=&#34;snap-lightbox-inner&#34;&gt;&#xA;          &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-heart-px.png&#34;  /&gt;&#xA;          &lt;p&gt;&#xA;          &lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close-button&#34;&gt;&lt;i class=&#34;snap-lightbox-x&#34;&gt;&lt;/i&gt;&lt;/a&gt;&#xA;      &lt;/div&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;As &lt;a href=&#34;http://blog.mehl.mx/2014/i-love-znc-because-ilovefs/&#34; title=&#34;I love ZNC because #ilovefs&#34;&gt;last year with ZNC&lt;/a&gt;, I want to say thank you to a specific project which easies my daily life. As you might know by other blog posts here, organisation of tasks, mails and almost everything else is a very important issue for me. So this year I want to write some lines about &lt;a href=&#34;http://taskwarrior.org/&#34;&gt;Taskwarrior&lt;/a&gt;, taskd and &lt;a href=&#34;http://mirakel.azapps.de/index.html&#34;&gt;Mirakel&lt;/a&gt; which enable me to take some free time without thinking of task which I could possibly forget to accomplish later on.&lt;/p&gt;&#xA;&lt;p&gt;My head is full of ideas and mental To-Do lists and so I’m in need of a handy tool which allows me to write down and organise items at any place and time: At my desk, in bus or train, when I’m offline or abroad. And its important that I don’t have (analog and digital) bits of paper everywhere, so I need a &lt;strong&gt;system that syncs all task inputs and outputs&lt;/strong&gt;. I tried a lot of tools but Taskwarrior was the best so far. It used the well-known „Getting Things Done“ concept with different priorities. Taskwarrior also supports tagging tasks, organising them in projects, due dates, postponing, making tasks dependend on others and much more. And Taskwarrior has a (modifiable) &lt;strong&gt;algorhythm that sorts your tasks by urgency levels&lt;/strong&gt;, so that the most important tasks always are on the top of the list. Even now I just took a glance at what Taskwarrior is able to do!&lt;/p&gt;&#xA;&#xA;&lt;figure class=&#34;md&#34;&gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &lt;a href=&#34;#fig2&#34;&gt;&#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-taskwarrior-gallery.jpg&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;        &lt;figcaption&gt;Someone who loves Taskwarrior as much as I do&lt;/figcaption&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;div class=&#34;snap-lightbox&#34; id=&#34;fig2&#34;&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close&#34;&gt;&lt;/a&gt;&#xA;        &lt;div class=&#34;snap-lightbox-inner&#34;&gt;&#xA;          &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-taskwarrior-gallery.jpg&#34;  /&gt;&#xA;          &lt;p&gt;Someone who loves Taskwarrior as much as I do&#xA;          &lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close-button&#34;&gt;&lt;i class=&#34;snap-lightbox-x&#34;&gt;&lt;/i&gt;&lt;/a&gt;&#xA;      &lt;/div&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;“&lt;em&gt;Services and programs that organise tasks aren’t very special!&lt;/em&gt;” one might think. But if you prefer sorting tasks digitally, you cannot simply chose a random todo-organising service provider. &lt;strong&gt;Most of the tools and services on the market aren’t free and transparent&lt;/strong&gt;. All input may no longer belong to you, all the gathered information (which is a lot if you think of it!) could be used for targeted ads or worse. You cannot modify the algorhythm to suit your needs. And what happens if the service provider goes bankrupt? All data, all project history and all pending tasks would be lost at once. So using a free (as in freedom), decentralised, maybe self-hosted service is the best idea to organise your tasks decentrally.&lt;/p&gt;&#xA;&lt;p&gt;But one thing at a time, let’s start from the very basic. You can install Taskwarrior and almost any operating system. After the installation, taskwarrior isn’t much more than a black window with white letters in it. And even when you’re a pro-user, you won’t find much more than white or colourful text on black background – and this is a good thing! I’ve seen no graphical user interface which can handle Taskwarrior’s complexity and the users‘ needs sufficiently (but &lt;a href=&#34;http://taskwarrior.org/tools/&#34;&gt;there are some&lt;/a&gt;, feel free to test them!). Nevertheless, &lt;strong&gt;it’s quite easy to use Taskwarrior&lt;/strong&gt; from your terminal:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task add &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;This is my first task&amp;#34;&lt;/span&gt;          &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add your first item&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task long                                 &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Show all pending tasks&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task add &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Second VIP task!&amp;#34;&lt;/span&gt; pri:H         &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add a task with priority&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task add &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Third task with tag&amp;#34;&lt;/span&gt; +test      &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add a task with a tag&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task add &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Fourth projected task&amp;#34;&lt;/span&gt; pro:Blog &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add a task with a project&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task long                                 &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Show all pending tasks&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;task &lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;                               &lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Mark first task as done (ID = 1)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are many useful and well understandable guides in the &lt;a href=&#34;http://taskwarrior.org/docs/&#34;&gt;project’s documentation&lt;/a&gt;. Most likely you do not need every command but maybe it’s useful to read something about techniques which might help you to organise your tasks your way.&lt;/p&gt;&#xA;&#xA;&lt;figure class=&#34;lg&#34;&gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &lt;a href=&#34;#fig3&#34;&gt;&#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-taskwarrior2.gif&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;        &lt;figcaption&gt;Some useful commands of Taskwarrior using some fish shell features&lt;/figcaption&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;div class=&#34;snap-lightbox&#34; id=&#34;fig3&#34;&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close&#34;&gt;&lt;/a&gt;&#xA;        &lt;div class=&#34;snap-lightbox-inner&#34;&gt;&#xA;          &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-taskwarrior2.gif&#34;  /&gt;&#xA;          &lt;p&gt;Some useful commands of Taskwarrior using some fish shell features&#xA;          &lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close-button&#34;&gt;&lt;i class=&#34;snap-lightbox-x&#34;&gt;&lt;/i&gt;&lt;/a&gt;&#xA;      &lt;/div&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;But Taskwarrior is only for your local computer. What’s if you want to use it when sitting in the bus and don’t want to forget a ToDo item you want to write down at the very moment? Then there’s a &lt;strong&gt;handy application for Android called&lt;/strong&gt; &lt;a href=&#34;http://mirakel.azapps.de/&#34;&gt;Mirakel&lt;/a&gt;. Even the app itself is powerful, but it’s full potential is unleashed when combining it with Taskwarrior. For this, &lt;strong&gt;we need a central instance&lt;/strong&gt; which synchronises the tasks you add or edit on your devices. The Taskwarrior project developed taskd for it which you can easily setup on a server. You can also use Mirakel’s own public taskd server (at least in the past) if you don’t own a server or don’t want to maintain this service.&lt;/p&gt;&#xA;&lt;p&gt;So if you connect both Taskwarrior and Mirakel to the new taskd server, you can easily share all tasks among them. When marking a task done on your smartphone, it’s marked as done on your home computer some seconds or minutes later if you want to. Security is an important part of taskwarrior as well, so transport encryption is on by default. And if you want, you can also try a &lt;a href=&#34;http://taskwarrior.org/tools/&#34;&gt;web interface&lt;/a&gt; or other handy tools and extensions for your server and client which I haven’t tested yet.&lt;/p&gt;&#xA;&lt;p&gt;Hopefully you now know a bit more about Taskwarrior and Mirakel and the great tools they designed. Of course I do not only want to recommend some software but also use this opportunity to say a big &lt;strong&gt;THANK YOU&lt;/strong&gt; to all the people behind these projects! Thank your for developing the software and making it compatible to each other. Thanks to the various contributors which are writing the important documentation, adding new languages, writing tools and bridges for other usage scenarios and thank you for reacting to bug reports. People like you make Free Software possible!&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>Yourls URL Shortener for Turpial</title>
      <link>https://mehl.mx/blog/2015/yourls-url-shortener-for-turpial/</link>
      <pubDate>Sat, 24 Jan 2015 01:58:32 +0000</pubDate>
      <guid>https://mehl.mx/blog/2015/yourls-url-shortener-for-turpial/</guid>
      <description>&lt;p&gt;Maybe you know &lt;a href=&#34;http://yourls.org/&#34;&gt;Yourls&lt;/a&gt;, a pretty cool URL shortener which you can set up on your own server very easily. Link shorteners are nice to have because&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;you can share long links with short urls and&lt;/li&gt;&#xA;&lt;li&gt;you can view and organise all links you ever shared (incl. statistics and so on).&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;There are many alternatives like bit.ly, ur1.ca and so on, but Yourls belongs to YOU and you don’t have to pay attention to ToS changes or the provider’s financial status. AND you can use whichever domain you own, for example in my case it’s &lt;em&gt;s.mehl.mx/blabla&lt;/em&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Maybe you know &lt;a href=&#34;http://yourls.org/&#34;&gt;Yourls&lt;/a&gt;, a pretty cool URL shortener which you can set up on your own server very easily. Link shorteners are nice to have because&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;you can share long links with short urls and&lt;/li&gt;&#xA;&lt;li&gt;you can view and organise all links you ever shared (incl. statistics and so on).&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;There are many alternatives like bit.ly, ur1.ca and so on, but Yourls belongs to YOU and you don’t have to pay attention to ToS changes or the provider’s financial status. AND you can use whichever domain you own, for example in my case it’s &lt;em&gt;s.mehl.mx/blabla&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;And maybe you also know &lt;a href=&#34;http://turpial.org.ve/&#34;&gt;Turpial&lt;/a&gt;, a Twitter client for GNU/Linux systems (I don’t like Twitter’s web page). Until lately I used Choqok, a KDE optimised client, but there were many things which annoyed me: No image previews, slow development, unconvenient reply behaviour and so on. And hey, why not trying something new? So I started to use Turpial which seems to solve all these critic points. Well, like always I missed some preferences to configure. But since it’s &lt;a href=&#34;https://fsfe.org/about/basics/freesoftware.html&#34;&gt;Free Software&lt;/a&gt;, one is able to look how the software works and to change it – and to share the improvements which I’ll do in the next step!&lt;/p&gt;&#xA;&lt;p&gt;Turpial already offers some link shorteners but not Yourls. But we can add it manually. To do so, open the file &lt;code&gt;/usr/lib/python2.7/dist-packages/libturpial/lib/services/url/shortypython/shorty.py&lt;/code&gt; as root. Now add the following somewhere between the already existing shorteners&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Yourls&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;Yourls&lt;/span&gt;(Service):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#00a000&#34;&gt;shrink&lt;/span&gt;(&lt;span style=&#34;color:#a2f&#34;&gt;self&lt;/span&gt;, bigurl):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;resp &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; request(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;http://YOUR_DOMAIN/yourls-api.php&amp;#39;&lt;/span&gt;, {&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;action&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;shorturl&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;format&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;xml&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;url&amp;#39;&lt;/span&gt;: bigurl, &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;signature&amp;#39;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;YOUR_SIGNATURE&amp;#39;&lt;/span&gt;})&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;returned_data &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; resp&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;read()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;matched_re &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; re&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;search(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;(http://YOUR_DOMAIN/[^&amp;#34;]+)&amp;#39;&lt;/span&gt;, returned_data)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; matched_re:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;return&lt;/span&gt; matched_re&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;group(&lt;span style=&#34;color:#666&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;else&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;raise&lt;/span&gt; ShortyError(&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;Failed to shrink url&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;yourls &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; Yourls()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Just replace &lt;code&gt;YOUR_DOMAIN&lt;/code&gt; and &lt;code&gt;YOUR_SIGNATURE&lt;/code&gt; accordingly. The usage of a signature enables you to hide your username and password when sending the shorten requests, like an API key and looks like &lt;code&gt;f51qw35w6&lt;/code&gt; (&lt;a href=&#34;https://github.com/YOURLS/YOURLS/wiki/PasswordlessAPI&#34;&gt;more about passwordlessAPI&lt;/a&gt;). You can retrieve your signature on your Yourls‘ Admin page via &lt;em&gt;Tools&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Then add the new service to the list of shorteners. In the same file search for &lt;code&gt;services = {&lt;/code&gt; (on the bottom) and add somewhere in the following list:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-py&#34; data-lang=&#34;py&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;yourls-instance&amp;#39;&lt;/span&gt;: yourls,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Well, then just restart Turpial, go to Preferences &amp;gt; Services and choose &lt;em&gt;yourls-instance&lt;/em&gt; from the list of Short URL services. Congrats, you should be able to short your URLs with Yourls in Turpial now :)&lt;/p&gt;&#xA;&lt;p&gt;Any problems or improvements? Drop me a message!&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;For me, only hardcoding the signature worked but not the prompt for these data like in some other services stated in the file&lt;/li&gt;&#xA;&lt;li&gt;Another file worth your attention might be &lt;code&gt;/usr/lib/python2.7/dist-packages/turpial/ui/qt/templates/style.css&lt;/code&gt;. There you can change colors, fonts and so on. For example, the &lt;em&gt;Ubuntu&lt;/em&gt; font wasn’t installed on my system so I just chose Sans Serif instead.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Sharing is caring – my Git instance</title>
      <link>https://mehl.mx/blog/2014/sharing-is-caring-my-git-instance/</link>
      <pubDate>Fri, 28 Nov 2014 17:16:50 +0000</pubDate>
      <guid>https://mehl.mx/blog/2014/sharing-is-caring-my-git-instance/</guid>
      <description>&lt;p&gt;Some days ago I noticed another time that I have far too little knowledge about Git.&lt;/p&gt;&#xA;&lt;p&gt;„Time to change that!“, I thought and set up &lt;a href=&#34;https://src.mehl.mx&#34;&gt;my own Git instance&lt;/a&gt; and also installed gitweb for better usability.&lt;/p&gt;&#xA;&lt;p&gt;Upside 1: I can keep track of the many (mainly bash) scripts I wrote in the past and all the changes I will adopt in the future.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Some days ago I noticed another time that I have far too little knowledge about Git.&lt;/p&gt;&#xA;&lt;p&gt;„Time to change that!“, I thought and set up &lt;a href=&#34;https://src.mehl.mx&#34;&gt;my own Git instance&lt;/a&gt; and also installed gitweb for better usability.&lt;/p&gt;&#xA;&lt;p&gt;Upside 1: I can keep track of the many (mainly bash) scripts I wrote in the past and all the changes I will adopt in the future.&lt;/p&gt;&#xA;&lt;p&gt;Upside 2: You can hopefully benefit from using and reading my code. All code is licensed under GNU GPL v3 so please feel free to use, study, share and improve my work!&lt;/p&gt;&#xA;&lt;p&gt;Some noteworthy projects I’m (a bit) proud of:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://src.mehl.mx/mxmehl/uni-surprising-newsfocus&#34;&gt;A seminar project with R to analyse over 300.000 SPON news articles whether and which country names appear&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://src.mehl.mx/mxmehl/mixcloud-dl&#34;&gt;Fast download of mixcloud sets without throttle&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://src.mehl.mx/mxmehl/pdf-clearmeta&#34;&gt;Easy to use script to delete all meta data from PDF files in a directory&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;And many more (and even more to come)! Have a look at &lt;a href=&#34;https://src.mehl.mx/&#34;&gt;src.mehl.mx&lt;/a&gt; for the whole list&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Any questions, ideas or improvements? Please contact me!&lt;/p&gt;&#xA;&lt;h3 id=&#34;update-26022016&#34;&gt;Update 26.02.2016&lt;/h3&gt;&#xA;&lt;p&gt;I washed away the quite basic gitweb instance and moved to Gogs. Here’s &lt;a href=&#34;https://blog.mehl.mx/2016/switching-my-code-from-gitweb-to-gogs/&#34;&gt;why and how&lt;/a&gt;. Links to the project may have changed because of that (and I’m too lazy to change them here).&lt;/p&gt;&#xA;</content:encoded>
    </item>
    <item>
      <title>Birthday Calendar with ownCloud via CalDAV</title>
      <link>https://mehl.mx/blog/2014/birthday-calendar-with-owncloud-via-caldav/</link>
      <pubDate>Wed, 17 Sep 2014 22:56:46 +0000</pubDate>
      <guid>https://mehl.mx/blog/2014/birthday-calendar-with-owncloud-via-caldav/</guid>
      <description>&lt;p&gt;Not a big issue in this blog post but an important one. Maybe I can save you some valuable time if you ever look for such a function.&lt;/p&gt;&#xA;&lt;p&gt;As you know I’m a heavy user of &lt;a href=&#34;http://owncloud.org&#34;&gt;ownCloud&lt;/a&gt; and you also might know that synchronisation is a big topic for me. And the third thing you should know that forgetting a good friend’s birthday really su&amp;hellip; well, it’s no good style. This almost happened to me some days ago because I couldn’t check it on my Notebook with Thunderbird. My setup looks like this: All contacts (with birthday tags) in ownCloud, and these CardDAV address books are synced with my Android phone and Thunderbird/&lt;a href=&#34;http://web.archive.org/web/20160123232734/http://www.sogo.nu:80/downloads/frontends.html&#34;&gt;SOGo-Connector&lt;/a&gt; on my notebook, as well as the CalDAV calendars with &lt;a href=&#34;http://web.archive.org/web/20170918023652/https://addons.mozilla.org/de/thunderbird/addon/lightning/&#34;&gt;Lightning&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Not a big issue in this blog post but an important one. Maybe I can save you some valuable time if you ever look for such a function.&lt;/p&gt;&#xA;&lt;p&gt;As you know I’m a heavy user of &lt;a href=&#34;http://owncloud.org&#34;&gt;ownCloud&lt;/a&gt; and you also might know that synchronisation is a big topic for me. And the third thing you should know that forgetting a good friend’s birthday really su&amp;hellip; well, it’s no good style. This almost happened to me some days ago because I couldn’t check it on my Notebook with Thunderbird. My setup looks like this: All contacts (with birthday tags) in ownCloud, and these CardDAV address books are synced with my Android phone and Thunderbird/&lt;a href=&#34;http://web.archive.org/web/20160123232734/http://www.sogo.nu:80/downloads/frontends.html&#34;&gt;SOGo-Connector&lt;/a&gt; on my notebook, as well as the CalDAV calendars with &lt;a href=&#34;http://web.archive.org/web/20170918023652/https://addons.mozilla.org/de/thunderbird/addon/lightning/&#34;&gt;Lightning&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;&lt;link rel=&#34;stylesheet&#34; href=&#34;https://mehl.mx/css/snap-gallery.css&#34; /&gt;&lt;figure class=&#34;sm pull-right no-border&#34;&gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/thunderbird-lightning.png&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;For Android there are &lt;a href=&#34;https://f-droid.org/repository/browse/?fdfilter=birthday&amp;amp;fdid=org.birthdayadapter&#34;&gt;several free software apps&lt;/a&gt; which enable the inclusion of birthdays from your contacts into any calendar app. Some calendar apps even can do it theirselves. But for Thunderbird there are only some outdated add-ons. All of them don’t work with TB31 anymore and if you modify the &lt;code&gt;install.rdf&lt;/code&gt;-file to make them run anyhow, they’re very buggy or just nonfunctional. And if you look in your ownCloud instance (where contacts‘ birthdays are visible in the calendar tab) for a downloadable/syncable calendar you’ll reach the same conclusion like me: There is none.&lt;/p&gt;&#xA;&lt;p&gt;But there is!&lt;/p&gt;&#xA;&lt;p&gt;And I only detected it while digging in some github issue threads. &lt;a href=&#34;https://github.com/owncloud/contacts/issues/67#issuecomment-30401668&#34;&gt;This post&lt;/a&gt; contains the rescuing link to a CalDAV/ICS calendar in any ownCloud version (I tested it in 7.0.2). Just modify and use following address in any application which supports CalDAV sync:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;http(s)://YOUR-OC-URL/remote.php/caldav/calendars/YOUR-USER/contact_birthdays&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;And you know what? It works like a charm! No need for external add-ons or apps, no need for manual creation of birthday reminders, no need for apologising for (almost) missed birthdays. I just wonder why ownCloud hasn’t included this in either the webpanel or the documentation. It’s a well-working feature since at least one year, so why not including it officially? And if it’s a calendar technically, then it should also be possible to disable displaying the contacts‘ birthdays in the webpanel calendar app – a still non-existent „feature“.&lt;/p&gt;&#xA;&lt;p&gt;So next time you have no excuse for forgetting a birthday – except for your ownCloud server&amp;rsquo;s outage ;)&lt;/p&gt;</content:encoded>
    </item>
    <item>
      <title>I love ZNC because #ilovefs</title>
      <link>https://mehl.mx/blog/2014/i-love-znc-because-ilovefs/</link>
      <pubDate>Fri, 14 Feb 2014 05:00:14 +0000</pubDate>
      <guid>https://mehl.mx/blog/2014/i-love-znc-because-ilovefs/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;Today is &lt;a href=&#34;http://ilovefs.org&#34;&gt;I love Free Software day 2014&lt;/a&gt;. Using the slogan „I love Free Software but I love you more“ this day should not only be used to thank our significant others for their love but also to say „thank you“ to people who work hard to ease one’s everyday tasks with the software they develop.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Have you ever been in an IRC channel?&lt;/p&gt;&#xA;&lt;p&gt;If not, you should try it, it’s a great and easy way of communication and very common.&lt;/p&gt;</description>
      <content:encoded>&lt;blockquote&gt;&#xA;&lt;p&gt;Today is &lt;a href=&#34;http://ilovefs.org&#34;&gt;I love Free Software day 2014&lt;/a&gt;. Using the slogan „I love Free Software but I love you more“ this day should not only be used to thank our significant others for their love but also to say „thank you“ to people who work hard to ease one’s everyday tasks with the software they develop.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Have you ever been in an IRC channel?&lt;/p&gt;&#xA;&lt;p&gt;If not, you should try it, it’s a great and easy way of communication and very common.&lt;/p&gt;&#xA;&#xA;&lt;link rel=&#34;stylesheet&#34; href=&#34;https://mehl.mx/css/snap-gallery.css&#34; /&gt;&lt;figure class=&#34;no-border&#34;&gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &#xA;      &lt;img src=&#34;http://fsfe.org/campaigns/ilovefs/artwork/graphics/ilovefs-banner-large-en.png&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;If yes, then the term „IRC Bouncer“ might be familiar to you. It keeps „you“ online 24/7 in the channel, although your device at home is offline. During this time, your slot in the channel is reserved by your bouncer.&lt;/p&gt;&#xA;&#xA;&lt;figure &gt;&#xA;  &lt;div class=&#34;snap-wrapper&#34;&gt;&#xA;    &lt;a href=&#34;#fig2&#34;&gt;&#xA;      &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-znc.png&#34; class=&#34;snap-thumb&#34;/&gt;&#xA;        &lt;figcaption&gt;Screenshot of ZNC&lt;/figcaption&gt;&#xA;    &lt;/a&gt;&#xA;    &lt;div class=&#34;snap-lightbox&#34; id=&#34;fig2&#34;&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close&#34;&gt;&lt;/a&gt;&#xA;        &lt;div class=&#34;snap-lightbox-inner&#34;&gt;&#xA;          &lt;img src=&#34;https://mehl.mx/img/blog/ilovefs-znc.png&#34;  /&gt;&#xA;          &lt;p&gt;Screenshot of ZNC&#xA;          &lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;a href=&#34;#_&#34; class=&#34;snap-lightbox-close-button&#34;&gt;&lt;i class=&#34;snap-lightbox-x&#34;&gt;&lt;/i&gt;&lt;/a&gt;&#xA;      &lt;/div&gt;&lt;/div&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;In this blog post, I’d like to present &lt;a href=&#34;http://wiki.znc.in/ZNC&#34;&gt;ZNC&lt;/a&gt; to you, a beautiful piece of &lt;a href=&#34;https://fsfe.org/about/basics/freesoftware.html&#34;&gt;Free Software&lt;/a&gt; which you can install easily on a server, is highly configurable and consumes only little server resources.&lt;/p&gt;&#xA;&lt;p&gt;„What the hell should this be for?!“ you’re asking? Well, since I’m presenting ZNC, I can give you a few examples of the mightyness of this software:&lt;/p&gt;&#xA;&lt;h2 id=&#34;features&#34;&gt;Features&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;If you’re leaving the channel, ZNC can set an individual away status and reply to anyone how’s calling you directly in the channel or in a query that you’re unavailable at the moment&lt;/li&gt;&#xA;&lt;li&gt;You can add multiple IRC networks with only one account and one port. Similar bouncers like psybnc are unable to do this. You can edit your networks separately, for example with different nicknames or away messages&lt;/li&gt;&#xA;&lt;li&gt;You don’t want to quit IRC even if you have to because the ongoing discussion is so interesting? No problem with ZNC. ZNC can buffer the channel chat and queries to you, so you can everything if you’re back again. This also helps if you had connection issues and come back a few minutes later – you’ll never miss anything again&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Well, these are only the basic functions. Below I added several others which have convinced me to keep using ZNC and nothing else. Of course, it’s Free Software (Apache 2.0 License) and it’s quite actively developed. If you have no server or no time to install something on it, you can also use one of the many &lt;a href=&#34;http://wiki.znc.in/Providers&#34;&gt;ZNC providers&lt;/a&gt; for free.&lt;/p&gt;&#xA;&lt;p&gt;If you like ZNC as much as I do, please consider &lt;a href=&#34;https://github.com/znc/znc&#34;&gt;helping them&lt;/a&gt; to improve the software or just &lt;a href=&#34;http://wiki.znc.in/ZNC:Site_support&#34;&gt;donate&lt;/a&gt; to keep the very useful wiki alive!&lt;/p&gt;&#xA;&lt;p&gt;Further cool functions you might find useful:&lt;/p&gt;&#xA;&lt;p&gt;Administration:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Installation is super-simple: Get the newest version, configure, make and make install. Then execute an configuration script which asks for the most important parameters while explaining them to you. Ready.&lt;/li&gt;&#xA;&lt;li&gt;Upgrade is very easy. Some days ago I upgraded from 0.2x to 1.2, a large version step. No problem at all, all configuration has been adapted&lt;/li&gt;&#xA;&lt;li&gt;Multi-user: You can set up an infinite amount of users per server/port, each with several networks.&lt;/li&gt;&#xA;&lt;li&gt;ZNC has a great webpanel which lets you administer everything. Of course, you can also do this directly in you IRC client if you’re connected&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Nerdy stuff:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;To protect you from suprises, you can enable modules like fail2ban (to block password bruteforcers), ctcpflood or crypt (to chat encrypted with other znc users without having them to install an extra plugin or client)&lt;/li&gt;&#xA;&lt;li&gt;You can automatically change your nick if you’re going offline. For example with „username_offline“ you make clear that you’re definitely not available&lt;/li&gt;&#xA;&lt;li&gt;You can create custom CTCP replies. Try to write &lt;code&gt;/ctcp USERNAME version&lt;/code&gt; and you’ll get detailed information about his IRC client. With ZNC, you can simply overwrite the default reply and send something generic instead&lt;/li&gt;&#xA;&lt;li&gt;You can even get shell access through your IRC client if you enable the function. Dunno what’s the advantage of this but it’s cool, right? ;)&lt;/li&gt;&#xA;&lt;/ul&gt;</content:encoded>
    </item>
    <item>
      <title>Mounting a SFTP storage in GNU/Linux</title>
      <link>https://mehl.mx/blog/2014/mounting-a-sftp-storage-in-gnu/linux/</link>
      <pubDate>Mon, 13 Jan 2014 14:42:01 +0000</pubDate>
      <guid>https://mehl.mx/blog/2014/mounting-a-sftp-storage-in-gnu/linux/</guid>
      <description>&lt;p&gt;This (longer than expected) post explains how to transfer files securely between your device and an external storage. The first part may be useful for you if you only have little knowledge of terms like (S)FTP(S) and want to learn something about widely used technologies. The second part will help you to mount an external storage so you can manage all files as if they are on your local device and the third, fourth and fifth part will concentrate on easing the mounting process by the help of hostnames, Private/Public Keys and a shell script.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;This (longer than expected) post explains how to transfer files securely between your device and an external storage. The first part may be useful for you if you only have little knowledge of terms like (S)FTP(S) and want to learn something about widely used technologies. The second part will help you to mount an external storage so you can manage all files as if they are on your local device and the third, fourth and fifth part will concentrate on easing the mounting process by the help of hostnames, Private/Public Keys and a shell script.&lt;/p&gt;&#xA;&lt;p&gt;This guide will be very detailed and is also (and especially) suited for beginners. Maybe also some advanced users can learn something or give hints for improvements.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: With improving Bash skills and more time, I was able to heavily improve the script in the end. Have a look at my &lt;a href=&#34;https://src.mehl.mx/mxmehl/network-mount&#34;&gt;Git instance&lt;/a&gt; to download the latest version.&lt;/p&gt;&#xA;&lt;p&gt;But let’s be honest: All in all, this post will show you again, why Free Software, GNU/Linux and Open Standards are great, easy to use and why Windows users are to be pitied.&lt;/p&gt;&#xA;&lt;h2 id=&#34;short-excursus&#34;&gt;Short excursus&lt;/h2&gt;&#xA;&lt;p&gt;(Nearly) everybody knows FTP. FTP is a protocol which enables you to transfer files between your device and a remote space. Maybe you want to present your documents or images to visitors of your homepage and simply want to upload these files on your webspace. In most cases this could be done by the use of a seperate program like FileZilla.&lt;/p&gt;&#xA;&lt;p&gt;So far so good, but there’re several problems. Two of them:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/File_Transfer_Protocol#Security&#34;&gt;FTP is insecure&lt;/a&gt;. Period.&lt;/li&gt;&#xA;&lt;li&gt;Using an external program (and not your personal file manager) is really annoying if you want to edit the files very often. A realistic example: You have a complicated script running on your website which you’d like to edit in a graphical editor. Using an external client forces you to download the file, open it in your editor, save it and upload it again. Some FTP clients like FileZilla have the functionality to ease this pain in the a**, but trust me: after the twentieth reupload you want to toss your computer away&amp;hellip;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Now we know why FTP is insecure. So what alternatives do we have?&lt;/p&gt;&#xA;&lt;p&gt;There is FTPS – using the FTP protocoll in connection with SSL. Well, that sounds great because, you know, SSL is great to ensure the safety of your online banking and frightens away &lt;a href=&#34;https://en.wikipedia.org/wiki/Packet_analyzer&#34;&gt;sniffing script kiddies&lt;/a&gt;. Forget that. FTPS is only securing the authentication process, the transfer of all files remains in plain text. So if you upload a sensitive document, it is fairly easy to intercept it on different levels in the uploading/downloading process. There is also the fact that FTPS is horrible to implement, not very compatible, and not very smart designed.&lt;/p&gt;&#xA;&lt;p&gt;The best alternative in my opinion is &lt;a href=&#34;https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol&#34;&gt;SFTP&lt;/a&gt;  (you are confused by all the abbreviations now? Wait for it, it gets better). SFTP uses a SSH connection to build a safe tunnel between your device and the remote storage. SSH is very smart, widely used and on most servers running a &lt;a href=&#34;https://en.wikipedia.org/wiki/Free_software&#34;&gt;Free&lt;/a&gt; operating system it is preinstalled and needs no further configuration. SFTP enforces you to transfer your files fully encrypted through a secure channel.&lt;/p&gt;&#xA;&lt;p&gt;But how to use it? You can use clients like FileZilla but do you remember the first problem I mentioned? Correct, an external editor is not what suits the needs of someone who wants to work with his files comfortably.&lt;/p&gt;&#xA;&lt;h2 id=&#34;mounting-an-external-storage-with-ssh&#34;&gt;Mounting an external storage with SSH&lt;/h2&gt;&#xA;&lt;p&gt;This sounds more complicated than it really is. The theory behind it is very easy: You mount (link) a remote directory over SSH (a secure channel) in any desired directory on your machine. For instance, you can simply edit all files in &lt;em&gt;/home/user/remote/&lt;/em&gt; with your programs, but finally all changes will happen (nearly) instantly on your remote storage. This even works with watching a video file that is located on the server: Open it like a normal video file in a player like VLC and it behaves like it is locally on your PC (if your internet connection is fast enough, just test it!).&lt;/p&gt;&#xA;&lt;p&gt;The only prerequisite: You need a server/webspace/storage with full SSH access. Unfortunately many webhosters don’t provide SSH access. If you belong to the unlucky ones, I recommend you to look for alternatives – it is worth it! (below this post, I added a very small list of webhosting providers offering SSH access)&lt;/p&gt;&#xA;&lt;p&gt;Now we come to the technical part. For this post, following data is used. Most likely, this will look different in your case.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SSH-Server: server1.net&#xA;Username on server: client&#xA;Home directory of user on server: /home/client&#xA;Username local machine: user&#xA;Local mount directory: /home/user/remote/server1&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On your GNU/Linux, please assure that following programs are installed. Some of them (ssh-askpass, zenity) are only used in step IV and V:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;openssh-client, sshfs, ssh-askpass, zenity&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now create a directory in which the remote storage should be mounted in. Don’t worry about the space on your hard disk: This directory is remote and there are only temporary files stored on your local device. In this example I’ll use &lt;em&gt;/home/user/remote/server1&lt;/em&gt;. It could also be &lt;em&gt;/fsfe/lol/wtf/nsa/&lt;/em&gt; if this directory would exist.&lt;/p&gt;&#xA;&lt;p&gt;Now, start a terminal/shell to fill in following commands as a normal user.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;ssh -p 22 client@server1.net&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;If asked for a password, fill in the password of ‚&lt;em&gt;client&lt;/em&gt;‚ (the webhoster should have given it to you). If you are now connected to the server1.net, you are just one step away from mounting it. Close the connection or terminal, open it again and type:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sshfs -p 22 client@server1.net: /home/user/remote/server1/ -o follow_symlinks&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;This command connects to ‚&lt;em&gt;server1.net&lt;/em&gt;‚ as the user ‚&lt;em&gt;client&lt;/em&gt;‚ using the SSH protocol over the standard &lt;em&gt;port&lt;/em&gt; 22. Then it mounts the home directory of ‚&lt;em&gt;client&lt;/em&gt;‚ on the local directory ‚&lt;em&gt;/home/user/remote/server1&lt;/em&gt;‚ which we created beforehand. Additionally we added the option ‚&lt;em&gt;follow_symlinks&lt;/em&gt;‚ so that links of the server work on our local machine as well. If you have a look at &lt;em&gt;/home/user/remote/server1&lt;/em&gt;, you should see the exact same content than in the home directory on your server or if you connect via FTP/SFTP. Congratulation! Now play around with it, try to edit, upload and download files.&lt;/p&gt;&#xA;&lt;p&gt;To unmount (speak: disconnect) the directory, type&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;fusermount -u /home/user/remote/server1&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now you mount the home directory of ‚client‘. If you want to mount another directory on the server (e.g. &lt;em&gt;/home/client/exchange&lt;/em&gt;), use this modified command:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sshfs -p 22 client@server1.net:/home/client/exchange/ /home/user/remote/server1/ -o follow_symlinks&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;In the next step, we will make the connection and mounting more comfortable, even if you are handling with more than one server.&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-hostnames&#34;&gt;Using hostnames&lt;/h2&gt;&#xA;&lt;p&gt;Now that you know how (and that) the system works, we will make it easier. Of course it is quite annoying to type in the whole server-address and port each time. Instead of &lt;em&gt;sshfs -p 22 &lt;a href=&#34;mailto:client@server1.net&#34;&gt;client@server1.net&lt;/a&gt;[…]&lt;/em&gt;, you can simply type &lt;em&gt;sshfs server1&lt;/em&gt;. How? Just open the SSH configuration file &lt;em&gt;/home/user/.ssh/config&lt;/em&gt; with you desired text editor and add:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Host server1&#xA;  HostName server1.net&#xA;  Port 22&#xA;  User client&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Save it and try to use this shortcut. It also works for normal SSH connection like ‚&lt;em&gt;ssh server1&lt;/em&gt;‚. For the &lt;em&gt;Host&lt;/em&gt; variable, you could use any name you can remember easily, for instance &lt;em&gt;privateserver&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-public-and-private-keys&#34;&gt;Using Public and Private Keys&lt;/h2&gt;&#xA;&lt;p&gt;Pretty smooth, isn’t it? Well, it gets even better! You have to admit that typing a password each time you connect is quite harrassing. This gets even worse if you are used to connect to many servers. On the one hand, you could use password managing tools&amp;hellip; or &lt;a href=&#34;https://en.wikipedia.org/wiki/Public-key_cryptography&#34;&gt;Public/Private key authentication&lt;/a&gt;! For those who don’t know much about it, let me say: This sounds terribly complicated, but you don’t have to understand it completely.&lt;/p&gt;&#xA;&lt;p&gt;For this guide, you only have to know: There are two keys (files). The one is private, you should never give it to anyone! It’s like a key to your safe, if someone achieves it, he can get everything that is secured in this safe. But the other file is public, you can give it to everyone if you want so. Now it gets a bit weird, so I try to make it as simple and abstract as possible.&lt;/p&gt;&#xA;&lt;p&gt;Let’s say, the public key is a chest that no one except the owner can open. Inside this chest, there is a supersecret word that no one except the owner knows. You put an exact copy of this chest on your server and each time you try to connect, you say „Hey, I’m the legitimate user of this server. Give me my chest, I will open it with my secret key and tell you, what the supersecret word is!“. The server will give you the chest (public key), you open it with your private key and tell the server the supersecret word. If you were right, the server lets you in.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This example is so ridiculously abstract that I had to laugh while writing it down. Every security expert, IT guy and cryptography scientist would knock me down for this but I hope it made you understand the principle of this very smart method. And if you ask yourself now „Why does the server know the supersecret word? Isn’t this insecure?“ or „Isn’t is insecure to send such a sensitive code word over the internet?“: You’re absolutely right! But be assured, that the public-key cryptography uses some awesome tricks to avoid security leaks like these and others. If you want to, read about it!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;It is quite easy to make this system happen. Again we need a terminal to generate the two keys:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;cd&lt;/span&gt; ~/.ssh/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ssh-keygen -t dsa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This neat script asks a.) in which file you want to save the new keys. The standard is set to &lt;em&gt;/home/user/.ssh/id_dsa&lt;/em&gt; and I recommend this. Most programs automatically search for keys in this destination. In step b.) it asks you for a password. This is quite important because if someone achieves your private key, he still needs a password to use it. After this short procedure, you have two new files in &lt;em&gt;/home/user/.ssh&lt;/em&gt; – id_dsa and id_dsa.pub. As you can imagine, id_dsa.pub is your public key, the other is the secret one.&lt;/p&gt;&#xA;&lt;p&gt;Now we have to put the public key (chest) on the server we want to connect to. This could be done by a simple command:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;ssh-copy-id -i /home/user/.ssh/id_dsa.pub client@server1.net&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;By this, you automatically connect as a legitimate user to your server (with the password used in step II) and put the public key in the &lt;em&gt;/home/client/.ssh/authorized_keys&lt;/em&gt;. This file simply collects all public keys (chests) of users that are allowed to connect to the server. If a stranger tries to connect to your server but there is no chest his secret key belongs to, he of course cannot open the connection to your server.&lt;/p&gt;&#xA;&lt;p&gt;Now disconnect from your server and try to connect via &lt;em&gt;ssh server1&lt;/em&gt;. Your device should automatically search for your private key and open the connection with it. As you notice, you are still asked for a password. This is because you (hopefully) put a password on your private key (remember?). But after you typed in the password once, it should be saved for duration of your local session in a local keyring.&lt;/p&gt;&#xA;&lt;p&gt;If this is not the case or you want to make your configuration even better, add the following lines on the bottom of your &lt;em&gt;/home/user/.bashrc&lt;/em&gt; (or if you’re not using bash, the respective rc file of your shell):&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;alias ssh=&#39;ssh-add -l &amp;gt; /dev/null || ssh-add -t 7200; ssh&#39;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;By this, you say to your shell: „Everytime I type the command ’ssh‘, you should instead (alias) 1.) check if I already added my key to the local keyring. If not so (||), 2.) add my key to the keyring, but only keep it there for 7200 seconds (you can also keep this away or increase it). Only if you made this sure, use the command ssh to connect to my server“. Every command line program that uses ssh to connect to a server (and there are some, e.g. git, sshfs…) now uses this procedure – no matter if you close the terminal or lock the screen.&lt;/p&gt;&#xA;&lt;p&gt;Of course, this also works with sshfs to mount your remote storages. If you remember our first line to mount the server, we have a much shorter line now without any password request:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sshfs server1: /home/user/remote/server1/ -o follow_symlinks&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;And these steps were quite important for the next section where we will write a shell script to make it much more easier – and even graphical!&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-a-shell-script&#34;&gt;Using a shell script&lt;/h2&gt;&#xA;&lt;p&gt;Our setting is very smooth now, but it could still be improved. If you want to connect to many servers and don’t want to use your shell every time or don’t want to remember the HOSTs you used in your .ssh/config, you’re free to modify and use this shell script:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;### VARIABLES TO BE CHANGED ###&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Preconfigured HOSTs in ~/.ssh/config that should be used&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PRESSH&lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;0&lt;span style=&#34;color:#666&#34;&gt;]=&lt;/span&gt;server1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PRESSH&lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;1&lt;span style=&#34;color:#666&#34;&gt;]=&lt;/span&gt;server2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PRESSH&lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt;2&lt;span style=&#34;color:#666&#34;&gt;]=&lt;/span&gt;server3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Local directory where the remote storages should be mounted to&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;LOCALMOUNTDIR&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;/home/user/remote&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;### THE SCRIPT BEGINS HERE ###&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Add SSH key to local keyring if not already happened&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;function&lt;/span&gt; sshadd &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;ssh-add -l &amp;gt; /dev/null &lt;span style=&#34;color:#666&#34;&gt;||&lt;/span&gt; ssh-add&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Choose preconfigured HOST to mount&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;function&lt;/span&gt; mount &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; ! &lt;span style=&#34;color:#b8860b&#34;&gt;SSH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;zenity --list &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;--height&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;300&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;--text&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Please choose. Cancel to unmount drives.&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;--title&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Choose SSH server&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;--column &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Preconfigured SSH servers&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;PRESSH&lt;/span&gt;[*]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;unmountquestion&#x9;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# If you press cancel, it should ask you to unmount all drives&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# If you double click on an entry, it gives &amp;#39;server1|server1&amp;#39; as result instead of &amp;#39;server1&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# This command cuts of everything after |&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#b8860b&#34;&gt;SSH&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b8860b&#34;&gt;$SSH&lt;/span&gt; | awk -F&lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\|&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#39;{ print $1 }&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Make a local directory if not available&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt; ! -e &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$LOCALMOUNTDIR&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;/&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$SSH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;mkdir -p &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$LOCALMOUNTDIR&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;/&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$SSH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Command to mount actually&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;sshfs &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$SSH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$LOCALMOUNTDIR&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;/&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$SSH&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;/ -o follow_symlinks &amp;amp;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;quitquestion&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# one more ssh server or quit?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Ask if all preconfigured SSHFS drives should be unmounted&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;function&lt;/span&gt; unmountquestion &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;zenity --question --text&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Unmount all preconfigured\nSSHFS drives now?&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$?&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;unmount&#x9;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# unmount function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a2f&#34;&gt;exit&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Procedure to unmount all preconfigured SSHFS drives and exit program afterwards&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;function&lt;/span&gt; unmount &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;((&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;i&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; 0; i &amp;lt; &lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${#&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;PRESSH&lt;/span&gt;[*]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;; i++&lt;span style=&#34;color:#666&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;fusermount -u &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$LOCALMOUNTDIR&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;/&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;PRESSH&lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;$i&lt;/span&gt;]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a2f&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;PRESSH&lt;/span&gt;[&lt;span style=&#34;color:#b8860b&#34;&gt;$i&lt;/span&gt;]&lt;span style=&#34;color:#b68;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34; unmounted.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f&#34;&gt;exit&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Should another SSHFS storage be mounted?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;function&lt;/span&gt; quitquestion &lt;span style=&#34;color:#666&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;zenity --question &lt;span style=&#34;color:#b62;font-weight:bold&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;--text&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;Mount another SSHFS storage?&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#b8860b&#34;&gt;$?&lt;/span&gt;&lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#b44&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&#x9;&lt;span style=&#34;color:#a2f&#34;&gt;exit&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#666&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sshadd&#x9;&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# sshadd function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# Loop for endless mounts until stopped by unmount or unmountquestion&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;while&lt;/span&gt; :&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;do&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#x9;mount&#x9;&lt;span style=&#34;color:#080;font-style:italic&#34;&gt;# mount function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a2f;font-weight:bold&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Save this script to some place (e.g. &lt;em&gt;/home/user/sftp-mount.sh&lt;/em&gt;) and make it executable (chmod +x /home/user/sftp-mount.sh). For example, you are now ready put a shortcut in your panel or on your desktop to make it easily accessible. Please note that zenity, sshfs and ssh-askpass should be installed.&lt;/p&gt;&#xA;&lt;p&gt;Please test the procedures written above on your servers and (if they have SSH access) webspaces. On my 4 webspaces and my vServer it works perfectly with my Debian Sid system. Please contact me or write in the comments if you have any problems or if some steps could be improved – nobody’s perfect :)&lt;/p&gt;&#xA;&lt;h2 id=&#34;appendix&#34;&gt;Appendix&lt;/h2&gt;&#xA;&lt;p&gt;I know following hosters that provide webspace with SSH access. This list is very short so please add more by writing in the comments!&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;uberspace.de (All plans, starting from 1,00€/mon, focussed on german residents) &amp;lt;– great hoster by the way!!&lt;/li&gt;&#xA;&lt;li&gt;OVH.com (&amp;gt;= Business Hosting, 5,94€/mon)&lt;/li&gt;&#xA;&lt;li&gt;HostGator.com (All plans, starting from 3,96$/mon)&lt;/li&gt;&#xA;&lt;li&gt;All-Inkl.com (&amp;gt;= Premium, 9,95€/mon)&lt;/li&gt;&#xA;&lt;li&gt;Hetzner.de (&amp;gt;= Level19, 19,90€/mon)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</content:encoded>
    </item>
  </channel>
</rss>
