<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://things.bleu255.com/runyourown/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=320x200</id>
	<title>Run Your Own - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://things.bleu255.com/runyourown/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=320x200"/>
	<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/Special:Contributions/320x200"/>
	<updated>2026-04-28T12:33:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=662</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=662"/>
		<updated>2025-08-17T15:05:45Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Request a wildcard cert for lurk.org */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Installation and maintenance ==&lt;br /&gt;
All commands are for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
=== Install ===&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
* upgrade&lt;br /&gt;
 acme.sh --uprade&lt;br /&gt;
* force renew already configured/installed certs&lt;br /&gt;
 acme.sh --renew-all --force &lt;br /&gt;
* what is wrong? (requires enabling logging in &amp;lt;code&amp;gt;account.conf&amp;lt;/code&amp;gt;)&lt;br /&gt;
 less /root/.acme.sh/acme.sh.log&lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Should be set and forget. Do not run the issue command again to force renew a cert, see maintenance section above.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory.  &amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Should be set and forget. Do not run this command to force renew a cert, see maintenance section above.&amp;lt;/span&amp;gt;&lt;br /&gt;
 mkdir /etc/nginx/certs&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
=== Fine tuning ===&lt;br /&gt;
The configured hook can be found listed in the domain name conf file (for instance &amp;lt;code&amp;gt;lurk.org.conf&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;Le_DeployHook=&#039;cooldaemon,anothercooldaemon,&#039;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=661</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=661"/>
		<updated>2025-08-17T15:04:32Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Install the certs for nginx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Installation and maintenance ==&lt;br /&gt;
All commands are for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
=== Install ===&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
* upgrade&lt;br /&gt;
 acme.sh --uprade&lt;br /&gt;
* force renew already configured/installed certs&lt;br /&gt;
 acme.sh --renew-all --force &lt;br /&gt;
* what is wrong? (requires enabling logging in &amp;lt;code&amp;gt;account.conf&amp;lt;/code&amp;gt;)&lt;br /&gt;
 less /root/.acme.sh/acme.sh.log&lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory.  &amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Should be set and forget. Do not run this command to force renew a cert, see maintenance section above.&amp;lt;/span&amp;gt;&lt;br /&gt;
 mkdir /etc/nginx/certs&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
=== Fine tuning ===&lt;br /&gt;
The configured hook can be found listed in the domain name conf file (for instance &amp;lt;code&amp;gt;lurk.org.conf&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;Le_DeployHook=&#039;cooldaemon,anothercooldaemon,&#039;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=660</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=660"/>
		<updated>2025-08-17T15:03:07Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Deployment for other services */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Installation and maintenance ==&lt;br /&gt;
All commands are for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
=== Install ===&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
* upgrade&lt;br /&gt;
 acme.sh --uprade&lt;br /&gt;
* force renew already configured/installed certs&lt;br /&gt;
 acme.sh --renew-all --force &lt;br /&gt;
* what is wrong? (requires enabling logging in &amp;lt;code&amp;gt;account.conf&amp;lt;/code&amp;gt;)&lt;br /&gt;
 less /root/.acme.sh/acme.sh.log&lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
=== Fine tuning ===&lt;br /&gt;
The configured hook can be found listed in the domain name conf file (for instance &amp;lt;code&amp;gt;lurk.org.conf&amp;lt;/code&amp;gt;): &amp;lt;code&amp;gt;Le_DeployHook=&#039;cooldaemon,anothercooldaemon,&#039;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=659</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=659"/>
		<updated>2025-08-17T15:00:05Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Old Stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Installation and maintenance ==&lt;br /&gt;
All commands are for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
=== Install ===&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
* upgrade&lt;br /&gt;
 acme.sh --uprade&lt;br /&gt;
* force renew already configured/installed certs&lt;br /&gt;
 acme.sh --renew-all --force &lt;br /&gt;
* what is wrong? (requires enabling logging in &amp;lt;code&amp;gt;account.conf&amp;lt;/code&amp;gt;)&lt;br /&gt;
 less /root/.acme.sh/acme.sh.log&lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:#00FF00&amp;quot;&amp;gt;Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=658</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=658"/>
		<updated>2025-08-17T14:58:17Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Installation and maintenance ==&lt;br /&gt;
All commands are for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;.&lt;br /&gt;
=== Install ===&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Maintenance ===&lt;br /&gt;
* upgrade&lt;br /&gt;
 acme.sh --uprade&lt;br /&gt;
* force renew already configured/installed certs&lt;br /&gt;
 acme.sh --renew-all --force &lt;br /&gt;
* what is wrong? (requires enabling logging in &amp;lt;code&amp;gt;account.conf&amp;lt;/code&amp;gt;)&lt;br /&gt;
 less /root/.acme.sh/acme.sh.log&lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=657</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=657"/>
		<updated>2025-08-17T14:47:31Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* set up a cron job */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
== Old Stuff ==&lt;br /&gt;
Left for future ref in case we need this again in the future. Otherwise, please ignore and do not use&lt;br /&gt;
&lt;br /&gt;
=== set up a cron job ===&lt;br /&gt;
 24 3 * * * &amp;quot;/root/.acme.sh&amp;quot;/acme.sh --cron --home &amp;quot;/root/.acme.sh&amp;quot; --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot; --renew-hook &amp;quot;/root/icecast_certs.sh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
To be fully modern and cool, we should probably switch from cron to a systemd timer but that&#039;s for another day. There&#039;s also a deploy script for icecast so this could theoretically all be done in one run but there are no docs for --cron so it&#039;s not clear how to set this up. For now we use a post renewal hook that smooshes the certs together for icecast:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
# turn the acme certs in to a certificate chain for icecast streaming&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
cat /root/.acme.sh/\*.lurk.org/\*.lurk.org.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
systemctl restart icecast&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Simple_LAN_filesharing_with_WebDAV&amp;diff=637</id>
		<title>Simple LAN filesharing with WebDAV</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Simple_LAN_filesharing_with_WebDAV&amp;diff=637"/>
		<updated>2024-12-30T12:33:59Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Linux filesystem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;WebDAV&#039;&#039;&#039; is both a quite popular and yet overlooked way to access and edit files remotely across a wide range of operating systems. Yes it&#039;s web stuff, again, but surprisingly fast, lightweight, and that can recover quite well on unstable networks or when the server has to be restarted, or has gone for lunch. A reason why it may be overlooked is possibly because it&#039;s often associated with sausage factories like own/nextcloud, or standalone implementations that are not particularly exciting. What is less known is that many web servers come with their own &#039;&#039;&#039;WebDAV&#039;&#039;&#039; implementation. Out of the usual suspects, &#039;&#039;&#039;nginx&#039;&#039;&#039;, &#039;&#039;&#039;Apache&#039;&#039;&#039;, and &#039;&#039;&#039;lighttpd&#039;&#039;&#039;,  the latter has both the most lightweight and most complete implementation. No need for anything else!&lt;br /&gt;
&lt;br /&gt;
In these notes we only cover a simple LAN setup, you can build upon it for more complex use case of course.&lt;br /&gt;
&lt;br /&gt;
== Server side ==&lt;br /&gt;
=== Installation ===&lt;br /&gt;
* This is for Debian, but I know you&#039;re smart, you will figure it out for &amp;lt;code&amp;gt;${FLAVOUR_OF_THE_MONTH_DISTRO}&amp;lt;/code&amp;gt;&lt;br /&gt;
 sudo apt install lighttpd lighttpd-mod-webdav&lt;br /&gt;
&lt;br /&gt;
=== Example Configuration ===&lt;br /&gt;
Basically the configuration that matters for now are in &amp;lt;code&amp;gt;/etc/lighttpd/conf-available&amp;lt;/code&amp;gt; and with symlinks in &amp;lt;code&amp;gt;/etc/lighttpd/conf-enabled&amp;lt;/code&amp;gt;. &#039;&#039;&#039;In our simple example we will have three shared folders, one that can be mounted read-only by anyone, and two that are read-write but require a username and password&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* By default a temp config file called &amp;lt;code&amp;gt;99-unconfigured.conf&amp;lt;/code&amp;gt; provides a generic landing page. We don&#039;t need it and we just have to enable the authentication config.&lt;br /&gt;
 sudo lighttpd-disable-mod unconfigured&lt;br /&gt;
 sudo lighttpd-enable-mod auth&lt;br /&gt;
* Create a user and password for the read-write share&lt;br /&gt;
 sudo apt install apache2-utils&lt;br /&gt;
 sudo htpasswd -c /etc/lighttpd/user.htpasswd turtleprincess heygirl&lt;br /&gt;
* create a new configuration file &amp;lt;code&amp;gt;/etc/lighttpd/conf-available/66-webdav.conf&amp;lt;/code&amp;gt; with the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server.modules += ( &amp;quot;mod_webdav&amp;quot; )&lt;br /&gt;
dir-listing.encoding = &amp;quot;utf-8&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
# This is needed for keepings tracks of locks and props which&lt;br /&gt;
# are needed for shares that can be edited&lt;br /&gt;
webdav.sqlite-db-name = &amp;quot;/var/cache/lighttpd/lighttpd.webdav.db&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
# auth&lt;br /&gt;
server.modules += (&amp;quot;mod_authn_file&amp;quot;)&lt;br /&gt;
auth.backend = &amp;quot;htpasswd&amp;quot; &lt;br /&gt;
auth.backend.htpasswd.userfile = &amp;quot;/etc/lighttpd/user.htpasswd&amp;quot;&lt;br /&gt;
auth.require = ( &amp;quot;/readwrite1&amp;quot;     =&amp;gt; ( &amp;quot;method&amp;quot; =&amp;gt; &amp;quot;basic&amp;quot;, &lt;br /&gt;
                                 &amp;quot;realm&amp;quot; =&amp;gt; &amp;quot;YOU WOT MATE&amp;quot;, &lt;br /&gt;
                                 &amp;quot;require&amp;quot; =&amp;gt; &amp;quot;valid-user&amp;quot; ),&lt;br /&gt;
                 &amp;quot;/readwrite2&amp;quot; =&amp;gt; ( &amp;quot;method&amp;quot; =&amp;gt; &amp;quot;basic&amp;quot;,&lt;br /&gt;
                                 &amp;quot;realm&amp;quot; =&amp;gt; &amp;quot;YOU WOT MATE&amp;quot;,&lt;br /&gt;
                                 &amp;quot;require&amp;quot; =&amp;gt; &amp;quot;valid-user&amp;quot; ))&lt;br /&gt;
  &lt;br /&gt;
# read-only stuff&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readonly(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readonly&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readonly&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.is-readonly = &amp;quot;enable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
# shared pit of madness&lt;br /&gt;
# for users listed in /etc/lighttpd/user.htpasswd&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readwrite1(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readwrite1&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readwrite1&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot;&lt;br /&gt;
    webdav.is-readonly = &amp;quot;disable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readwrite2(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readwrite2&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readwrite2&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot;&lt;br /&gt;
    webdav.is-readonly = &amp;quot;disable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now if you wonder what kind of magic will happen so that the lighttpd process, local and remote users can happily live together ever after, and edit the same files, well, none. It won&#039;t happen just like this, it does not work and you will be sad. Then you will start binge drinking to forget about server administration. You will go in the streets, pick up fights with strangers who are in a much better physical condition because they don&#039;t spend hours configuring neovim plugins that &#039;&#039;you haven&#039;t even used once&#039;&#039;. It will be painful. So to avoid this unfortunate situation you need to do two things:&lt;br /&gt;
&lt;br /&gt;
* First, the folder needs to be group-owned by the lighttpd process owner, in our case, on Debian, it&#039;s &amp;lt;code&amp;gt;www-data&amp;lt;/code&amp;gt;. You also need to set the group ID bit on the folder you intend to use as WedDAV share, so that all newly created files will inherit the group ownership of this folder.&lt;br /&gt;
 sudo chown regular_user:www-data /local/path/to/readwrite1&lt;br /&gt;
 sudo chmod g+ws /local/path/to/readwrite1&lt;br /&gt;
* Second, you need to change the way lighttpd is started so that its umask is set in a way that any permission may be set for user and group (default is just user). On a systemd based system (haters gonna hate) you need to edit &amp;lt;code&amp;gt;/etc/systemd/system/lighttpd.service&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
 ExecStart=/bin/sh -c &#039;umask 002;/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf&#039;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it, you have a working simple LAN filesharing with WebDAV check the documentation for more options, and more fun config time, at home, where it&#039;s much safer for you.&lt;br /&gt;
&lt;br /&gt;
== Client side ==&lt;br /&gt;
=== Web browser ===&lt;br /&gt;
The nice advantage of the setup above is that all the files can be readily browsed at the local IP of the machine running lighttpd, for instance http://192.168.100.100/readonly. If you&#039;re into web stuff have a look at https://github.com/dom111/webdav-js, it would be really trivial to serve this js file with the lighttpd server and provide more functionality than just browsing and downloading.&lt;br /&gt;
&lt;br /&gt;
=== Linux filesystem ===&lt;br /&gt;
Mounting a WebDAV on Linux is straightforward with &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; and requires minimal configuration. &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; is also able to recover quite well from disconnections and potential read/write fuckery (there is a daemon and a local cache, but you don&#039;t need to worry about this). If the server is dead, that you need to poweroff your machine, and you still have something mounted, it&#039;s a good idea to unmount things first to speed up shutdown. No it won&#039;t lock like a little NFS shit but there is a timeout and you&#039;re a busy person.&lt;br /&gt;
* To mount manually the read-only folder from above:&lt;br /&gt;
 sudo apt install davfs2&lt;br /&gt;
 sudo mount -t davfs http://192.168.100.100/readonly /mnt/readonly&lt;br /&gt;
* To remember username passwords you can create a personal &amp;lt;code&amp;gt;~/.davfs2/secrets&amp;lt;/code&amp;gt; file with:&lt;br /&gt;
 http://192.168.100.100/readwrite1 turtleprincess heygirl&lt;br /&gt;
 http://192.168.100.100/readwrite2 turtleprincess heygirl&lt;br /&gt;
 etc&lt;br /&gt;
* permissions matters&lt;br /&gt;
 chmod 600 ~/.davfs2/secrets&lt;br /&gt;
* You can also have everything configured in your &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt; and then mount everything as a regular user:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# My cool LAN WebDAV thing&lt;br /&gt;
http://192.168.100.100/readonly    /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
http://192.168.100.100/readwrite1  /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
http://192.168.100.100/readwrite2  /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FreeBSD filesystem ===&lt;br /&gt;
On FreeBSD it&#039;s basically the same as on Linux. lol. Of course not! What did you think? That would be too easy. You need to work hard to earn your condescending smug BSD coolness. At time of writing, &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; is being [https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267518 ported to FreeBSD by its author]. Don&#039;t hold your breath, but hopefully this will happen because the FreeBSD usual way to mount WebDAV stuff with &amp;lt;code&amp;gt;mount.webdavfs&amp;lt;/code&amp;gt; just sucks (&amp;quot;Device not configured&amp;quot; on certain reading operations, not able to recover when the server disconnects). As a workaround, the all-you-can-eat-software-buffet &amp;lt;code&amp;gt;rclone&amp;lt;/code&amp;gt; is the only reliable way to have WebDAV mounted in a FreeBSD filesystem.&lt;br /&gt;
&lt;br /&gt;
* installation&lt;br /&gt;
 pkg install rclone # yeah yeah you can use portmaster and disable stuff you will regret later&lt;br /&gt;
* load fuse&lt;br /&gt;
 sudo kldload fusefs&lt;br /&gt;
* to make it permanent add the following to &amp;lt;code&amp;gt;/boot/loader.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Filesystems in Userspace&lt;br /&gt;
 fusefs_load=&amp;quot;YES&lt;br /&gt;
* create a &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt; config file with:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[192.168.100.100]&lt;br /&gt;
type = webdav&lt;br /&gt;
url = http://192.168.100.100/&lt;br /&gt;
vendor = other&lt;br /&gt;
user = turtleprincess&lt;br /&gt;
pass = SEE_BELOW&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works&lt;br /&gt;
 sudo mkdir /mnt/readwrite2&lt;br /&gt;
 sudo chown user:user /mnt/readwrite2&lt;br /&gt;
 rclone mount 192.168.100.100:readwrite2 /mnt/readwrite2/ --vfs-cache-mode writes --daemon&lt;br /&gt;
&lt;br /&gt;
You can also make entries in your &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
* rclone can&#039;t really be used directly, so we will trick fuse&lt;br /&gt;
 sudo ln -s /usr/local/bin/rclone /usr/local/bin/mount.rclone&lt;br /&gt;
* in &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# My cool LAN WebDAV thing&lt;br /&gt;
192.168.100.100:readonly     /mnt/readonly    fuse noauto,ro,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
192.168.100.100:readwrite1   /mnt/readwrite1  fuse noauto,rw,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
192.168.100.100:readwrite1   /mnt/readwrite1  fuse noauto,rw,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nautilus ===&lt;br /&gt;
For those into GUI (not judging, it&#039;s a free country) WebDAV is really easy to access thanks to the GVfs daemon. It&#039;s also a solid option in terms of recovery and making sure little to no fuckery is possible when writing on an unstable network. In practice, click on the &amp;quot;other&amp;quot; location button on the left pane, choose WedDAV and enter the URL in the form of &amp;lt;code&amp;gt;dav://192.168.100.100/readwrite1&amp;lt;/code&amp;gt; and give your credentials. The only caveat is that the mounted folder name will be the server name, only the server name (IP in this case), so you may want to add your share to the bookmarks, and rename the bookmark to something more meaningful.&lt;br /&gt;
&lt;br /&gt;
=== Android ===&lt;br /&gt;
Several commercial, closed source options. We don&#039;t talk to these people. There are however three interesting FLOSS options:&lt;br /&gt;
* https://github.com/newhinton/Round-Sync - super complete, multiple network file storage supported (based on rclone)&lt;br /&gt;
* https://github.com/phpbg/easysync - minimal automated WebDAV sync for the usual Android user data folders&lt;br /&gt;
* https://github.com/bitfireAT/davx5-ose - focused on CalDAV/CardDAV but hidden in one menu there is a mini browsing option for WebDAV&lt;br /&gt;
&lt;br /&gt;
=== Nintendo Switch ===&lt;br /&gt;
Because you know, reasons:&lt;br /&gt;
* https://github.com/cy33hc/switch-ezremote-client - simple file browser/editor&lt;br /&gt;
* https://github.com/J-D-K/JKSV - popular save file manager, a WebDAV folder can be the default folder to export save backups&lt;br /&gt;
&lt;br /&gt;
== Pro Tips ==&lt;br /&gt;
* IPs are used above but you can use a local DNS or make use of your local &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; files to give a nice name to your WedDAV server, look into RFC 8375 for pointers.&lt;br /&gt;
* To debug things if things are not behaving as nice things:&lt;br /&gt;
 lighttpd-enable-mod accesslog&lt;br /&gt;
 systemctl restart lighttpd&lt;br /&gt;
 tail -f /var/log/lighttpd/access.log&lt;br /&gt;
 # 17.4 hours later&lt;br /&gt;
 # Problem solved at last&lt;br /&gt;
 lighttpd-disable-mod accesslog&lt;br /&gt;
 systemctl restart lighttpd&lt;br /&gt;
&lt;br /&gt;
[[Category: WebDAV]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=635</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=635"/>
		<updated>2024-10-12T23:06:31Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Deployment for other services */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; can also support custom installs of the certificates. They call this deployment, and all the scripts provided by the project can be found in &amp;lt;code&amp;gt;/root/.acme.sh/deploy&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s possible to make new deploy scripts quite easily, here is an example for &amp;lt;code&amp;gt;cooldaemon.sh&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# this makes accessible as variables all the necessary paths and files&lt;br /&gt;
cooldaemon_deploy() {&lt;br /&gt;
_cdomain=&amp;quot;$1&amp;quot;&lt;br /&gt;
_ckey=&amp;quot;$2&amp;quot;&lt;br /&gt;
_ccert=&amp;quot;$3&amp;quot;&lt;br /&gt;
_cca=&amp;quot;$4&amp;quot;&lt;br /&gt;
_cfullchain=&amp;quot;$5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
_debug _cdomain &amp;quot;$_cdomain&amp;quot;&lt;br /&gt;
_debug _ckey &amp;quot;$_ckey&amp;quot;&lt;br /&gt;
_debug _ccert &amp;quot;$_ccert&amp;quot;&lt;br /&gt;
_debug _cca &amp;quot;$_cca&amp;quot;&lt;br /&gt;
_debug _cfullchain &amp;quot;$_cfullchain&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# make a var for the target location&lt;br /&gt;
_ssl_path=&amp;quot;/etc/cooldaemon/certs/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cooldaemon only needs the fullchain perm and the key so&lt;br /&gt;
# we only copy these&lt;br /&gt;
cp $_ckey $_ssl_path&lt;br /&gt;
cp $_cfullchain $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# any extra commands can be added here for instance&lt;br /&gt;
# maybe cooldaemon is picky about cert ownership&lt;br /&gt;
chown -R cooldaemon:cooldaemon $_ssl_path&lt;br /&gt;
&lt;br /&gt;
# last but not least we reload cool daemon&lt;br /&gt;
# please note that some other daemons may need a restart instead&lt;br /&gt;
systemctl reload mumble-server&lt;br /&gt;
&lt;br /&gt;
return 0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To enable the deployment at every cert renewal:&lt;br /&gt;
 acme.sh --deploy -d lurk.org -d *.lurk.org --deploy-hook cooldaemon&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=634</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=634"/>
		<updated>2024-10-12T22:55:42Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Install the certs for nginx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
The following command will install the certs for nginx, assuming there is a &amp;lt;code&amp;gt;/etc/nginx/certs/&amp;lt;/code&amp;gt; directory. Should be set and forget.&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=633</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=633"/>
		<updated>2024-10-12T22:39:17Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Install the certs for nginx */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
 acme.sh --install-cert -d lurk.org -d *.lurk.org --key-file /etc/nginx/certs/key.pem --fullchain-file /etc/nginx/certs/cert.pem --reloadcmd &amp;quot;systemctl force-reload nginx&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=632</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=632"/>
		<updated>2024-10-12T22:34:01Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
We use wildcard certificates with DNS authentification, and we use the DNS server of our registrar, porkbun. It&#039;s not great (terrible UI for DNS editing), but it&#039;s cheap. Porkbun DNS support was added in recent versions of &amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt;. To make it work, we first need to find our Porkbun API keys and use them to set the following environment variables in root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 export PORKBUN_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
 export PORKBUN_SECRET_API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
When ready and reloaded:&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_porkbun -d lurk.org -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
result:&lt;br /&gt;
&lt;br /&gt;
* cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* cert key is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/lurk.org.key&amp;lt;/code&amp;gt;&lt;br /&gt;
* intermediate CA cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/ca.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
* full-chain cert is in: &amp;lt;code&amp;gt;/root/.acme.sh/lurk.org_ecc/fullchain.cer&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Let%27s_Encrypt_Wildcard_Certificates&amp;diff=631</id>
		<title>Let&#039;s Encrypt Wildcard Certificates</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Let%27s_Encrypt_Wildcard_Certificates&amp;diff=631"/>
		<updated>2024-10-12T22:05:11Z</updated>

		<summary type="html">&lt;p&gt;320x200: 320x200 moved page Let&amp;#039;s Encrypt Wildcard Certificates to Wildcard Certificates with acme.sh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Wildcard Certificates with acme.sh]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=630</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=630"/>
		<updated>2024-10-12T22:05:11Z</updated>

		<summary type="html">&lt;p&gt;320x200: 320x200 moved page Let&amp;#039;s Encrypt Wildcard Certificates to Wildcard Certificates with acme.sh&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
&lt;br /&gt;
We use wildcard certificates with DNS authentification&lt;br /&gt;
first find and export the gandi dns key:&lt;br /&gt;
&lt;br /&gt;
 export GANDI_LIVEDNS_KEY=&amp;quot;fdmlfsdklmfdkmqsdfk&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Then request a wildcard cert. (the dns key is added to a config file automatically for future renewals)&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_gandi_livedns --nginx -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
Find the certs in:&lt;br /&gt;
&lt;br /&gt;
 /root/.acme.sh/\*.lurk.org/&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=629</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=629"/>
		<updated>2024-10-12T22:04:29Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates, etc.&lt;br /&gt;
&lt;br /&gt;
== Install the bash script ==&lt;br /&gt;
&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Request a wildcard cert for lurk.org ==&lt;br /&gt;
&lt;br /&gt;
We use wildcard certificates with DNS authentification&lt;br /&gt;
first find and export the gandi dns key:&lt;br /&gt;
&lt;br /&gt;
 export GANDI_LIVEDNS_KEY=&amp;quot;fdmlfsdklmfdkmqsdfk&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Then request a wildcard cert. (the dns key is added to a config file automatically for future renewals)&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_gandi_livedns --nginx -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
Find the certs in:&lt;br /&gt;
&lt;br /&gt;
 /root/.acme.sh/\*.lurk.org/&lt;br /&gt;
&lt;br /&gt;
== Install the certs for nginx ==&lt;br /&gt;
&lt;br /&gt;
== Deployment for other services ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=628</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=628"/>
		<updated>2024-10-12T21:59:11Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Using acme.sh ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;acme.sh&amp;lt;/code&amp;gt; is a lightweight shell script based tool to handle Let&#039;s Encrypt certificates.&lt;br /&gt;
&lt;br /&gt;
=== Install the bash script ===&lt;br /&gt;
&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to &amp;lt;code&amp;gt;/root/.acme&amp;lt;/code&amp;gt; and add it to path by sourcing a script from root&#039;s &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Request a wildcard cert for lurk.org ===&lt;br /&gt;
&lt;br /&gt;
We use wildcard certificates with DNS authentification&lt;br /&gt;
first find and export the gandi dns key:&lt;br /&gt;
&lt;br /&gt;
 export GANDI_LIVEDNS_KEY=&amp;quot;fdmlfsdklmfdkmqsdfk&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Then request a wildcard cert. (the dns key is added to a config file automatically for future renewals)&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_gandi_livedns --nginx -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
Find the certs in:&lt;br /&gt;
&lt;br /&gt;
 /root/.acme.sh/\*.lurk.org/&lt;br /&gt;
&lt;br /&gt;
=== Install the certs for nginx ===&lt;br /&gt;
&lt;br /&gt;
=== Deployment for other services ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Streaming_Service_with_Icecast&amp;diff=626</id>
		<title>Streaming Service with Icecast</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Streaming_Service_with_Icecast&amp;diff=626"/>
		<updated>2024-07-17T22:03:44Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* TLS/SSL Support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Note:&#039;&#039;&#039; we will be using the &amp;lt;code&amp;gt;icecast-kh&amp;lt;/code&amp;gt; fork that contains [https://github.com/karlheyes/icecast-kh/blob/master/NEWS some extra stuff and features/fixes/improvements] that may eventually land in vanilla &amp;lt;code&amp;gt;icecast&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Installation for a Simple Setup ==&lt;br /&gt;
=== Software ===&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; At time of writing, &amp;lt;code&amp;gt;icecast-kh&amp;lt;/code&amp;gt; suffers from [https://github.com/karlheyes/icecast-kh/issues/260 a small compilation problem with OpenSSL].&lt;br /&gt;
&lt;br /&gt;
* Install dependencies (Debian)&lt;br /&gt;
 apt install libxslt1-dev libogg-dev libvorbis-dev libtheora-dev libcurl4-openssl-dev&lt;br /&gt;
* Get the sources&lt;br /&gt;
 cd /usr/src&lt;br /&gt;
 git clone https://github.com/karlheyes/icecast-kh&lt;br /&gt;
* Compile and install&lt;br /&gt;
 cd icecast-kh&lt;br /&gt;
 ./configure --with-openssl&lt;br /&gt;
 make&lt;br /&gt;
 make install&lt;br /&gt;
&lt;br /&gt;
=== Firewall ===&lt;br /&gt;
* Make sure you listen on 8000, adjust your &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;:&lt;br /&gt;
 -A INPUT -p tcp -m tcp --dport 8000 -j ACCEPT&lt;br /&gt;
&lt;br /&gt;
You can adjust to your liking, 8000 is the default for Icecast.&lt;br /&gt;
&lt;br /&gt;
=== Basic Configuration ===&lt;br /&gt;
Simple setup with &amp;lt;code&amp;gt;icecast&amp;lt;/code&amp;gt; accepting 4 sources, changing process ownership to &amp;lt;code&amp;gt;nobody:nogroup&amp;lt;/code&amp;gt;, and running in a &amp;lt;code&amp;gt;chroot&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* log files in chroot:&lt;br /&gt;
 mkdir /usr/local/share/icecast/log&lt;br /&gt;
 chown nobody:nogroup /usr/local/share/icecast/log&lt;br /&gt;
* &amp;lt;code&amp;gt;/usr/local/etc/icecast.xml&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;icecast&amp;gt;&lt;br /&gt;
      &amp;lt;location&amp;gt;𓅣&amp;lt;/location&amp;gt;&lt;br /&gt;
      &amp;lt;admin&amp;gt;top.cool@c_est.super.deluxe&amp;lt;/admin&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;limits&amp;gt;&lt;br /&gt;
          &amp;lt;clients&amp;gt;64&amp;lt;/clients&amp;gt;&lt;br /&gt;
          &amp;lt;sources&amp;gt;4&amp;lt;/sources&amp;gt;&lt;br /&gt;
          &amp;lt;queue-size&amp;gt;524288&amp;lt;/queue-size&amp;gt;&lt;br /&gt;
          &amp;lt;client-timeout&amp;gt;30&amp;lt;/client-timeout&amp;gt;&lt;br /&gt;
          &amp;lt;header-timeout&amp;gt;15&amp;lt;/header-timeout&amp;gt;&lt;br /&gt;
          &amp;lt;source-timeout&amp;gt;10&amp;lt;/source-timeout&amp;gt;&lt;br /&gt;
          &amp;lt;burst-size&amp;gt;65535&amp;lt;/burst-size&amp;gt;&lt;br /&gt;
      &amp;lt;/limits&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;authentication&amp;gt;&lt;br /&gt;
          &amp;lt;source-password&amp;gt;hackme&amp;lt;/source-password&amp;gt;&lt;br /&gt;
          &amp;lt;relay-password&amp;gt;hackme&amp;lt;/relay-password&amp;gt;&lt;br /&gt;
          &amp;lt;admin-user&amp;gt;admin&amp;lt;/admin-user&amp;gt;&lt;br /&gt;
          &amp;lt;admin-password&amp;gt;hackme&amp;lt;/admin-password&amp;gt;&lt;br /&gt;
      &amp;lt;/authentication&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;hostname&amp;gt;stream.domain.tld&amp;lt;/hostname&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;listen-socket&amp;gt;&lt;br /&gt;
          &amp;lt;port&amp;gt;8000&amp;lt;/port&amp;gt;&lt;br /&gt;
      &amp;lt;/listen-socket&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;fileserve&amp;gt;1&amp;lt;/fileserve&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;paths&amp;gt;&lt;br /&gt;
          &amp;lt;basedir&amp;gt;/usr/local/share/icecast&amp;lt;/basedir&amp;gt;&lt;br /&gt;
          &amp;lt;logdir&amp;gt;/log&amp;lt;/logdir&amp;gt;&lt;br /&gt;
          &amp;lt;webroot&amp;gt;/web&amp;lt;/webroot&amp;gt;&lt;br /&gt;
          &amp;lt;adminroot&amp;gt;/admin&amp;lt;/adminroot&amp;gt;&lt;br /&gt;
          &amp;lt;alias source=&amp;quot;/&amp;quot; dest=&amp;quot;/index.html&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;/paths&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;logging&amp;gt;&lt;br /&gt;
          &amp;lt;accesslog&amp;gt;access.log&amp;lt;/accesslog&amp;gt;&lt;br /&gt;
          &amp;lt;errorlog&amp;gt;error.log&amp;lt;/errorlog&amp;gt;&lt;br /&gt;
          &amp;lt;loglevel&amp;gt;1&amp;lt;/loglevel&amp;gt; &amp;lt;!-- 4 Debug, 3 Info, 2 Warn, 1 Error --&amp;gt;&lt;br /&gt;
          &amp;lt;logsize&amp;gt;10000&amp;lt;/logsize&amp;gt; &amp;lt;!-- Max size of a logfile --&amp;gt;&lt;br /&gt;
       &amp;lt;/logging&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
      &amp;lt;security&amp;gt;&lt;br /&gt;
          &amp;lt;chroot&amp;gt;1&amp;lt;/chroot&amp;gt;&lt;br /&gt;
          &amp;lt;changeowner&amp;gt;&lt;br /&gt;
              &amp;lt;user&amp;gt;nobody&amp;lt;/user&amp;gt;&lt;br /&gt;
              &amp;lt;group&amp;gt;nogroup&amp;lt;/group&amp;gt;&lt;br /&gt;
          &amp;lt;/changeowner&amp;gt;&lt;br /&gt;
      &amp;lt;/security&amp;gt;&lt;br /&gt;
  &amp;lt;/icecast&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Service file and autostart (systemd) ===&lt;br /&gt;
* Create a &amp;lt;code&amp;gt;/etc/systemd/system/icecast.service&amp;lt;/code&amp;gt; unit file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[Unit]&lt;br /&gt;
Description=Icecast&lt;br /&gt;
After=network.target&lt;br /&gt;
&lt;br /&gt;
[Service]&lt;br /&gt;
Type=simple&lt;br /&gt;
ExecStart=/usr/local/bin/icecast -c /usr/local/etc/icecast.xml&lt;br /&gt;
ExecReload=/usr/bin/kill -HUP $MAINPID&lt;br /&gt;
&lt;br /&gt;
[Install]&lt;br /&gt;
WantedBy=multi-user.target&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Enable the service on boot:&lt;br /&gt;
 systemctl enable icecast&lt;br /&gt;
* Manage the service with&lt;br /&gt;
 service icecast start&lt;br /&gt;
 service icecast status&lt;br /&gt;
 service icecast stop&lt;br /&gt;
&lt;br /&gt;
== MOAR Configuration ==&lt;br /&gt;
With the previous section you will get something up and running, stable and all. It&#039;s a good starting point to tweak things further.&lt;br /&gt;
&lt;br /&gt;
=== NGINX Reverse Proxy ===&lt;br /&gt;
At time of writing, reverse proxying for icecast is not really worth it. Will explain a bit more eventually.&lt;br /&gt;
&lt;br /&gt;
=== TLS/SSL Support ===&lt;br /&gt;
It&#039;s possible to use existing X.509 certificates to provide HTTPS access to both listeners and sources. For this to work the server and intermediate certificates with the private key.&lt;br /&gt;
* merge &amp;lt;code&amp;gt;fullchain.pem&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;privkey.pem&amp;lt;/code&amp;gt;&lt;br /&gt;
 # official acme client&lt;br /&gt;
 cat /etc/letsencrypt/live/domain.tld/fullchain.pem &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
 cat /etc/letsencrypt/live/domain.tld/privkey.pem &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
 # acme.sh&lt;br /&gt;
 cat /root/.acme.sh/domain.tld/fullchain.cer &amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
 cat /root/.acme.sh/domain.tld/domain.tld.key &amp;gt;&amp;gt; /usr/local/share/icecast/icecast.pem&lt;br /&gt;
* Adjust &amp;lt;code&amp;gt;icecast.xml&amp;lt;/code&amp;gt; config file with &amp;lt;code&amp;gt;&amp;lt;ssl-certificate&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;ssl-allowed-ciphers&amp;gt;&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      &amp;lt;paths&amp;gt;&lt;br /&gt;
          &amp;lt;basedir&amp;gt;/usr/local/share/icecast&amp;lt;/basedir&amp;gt;&lt;br /&gt;
          &amp;lt;logdir&amp;gt;/log&amp;lt;/logdir&amp;gt;&lt;br /&gt;
          &amp;lt;webroot&amp;gt;/web&amp;lt;/webroot&amp;gt;&lt;br /&gt;
          &amp;lt;adminroot&amp;gt;/admin&amp;lt;/adminroot&amp;gt;&lt;br /&gt;
          &amp;lt;ssl-certificate&amp;gt;/usr/local/share/icecast/icecast.pem&amp;lt;/ssl-certificate&amp;gt;&lt;br /&gt;
          &amp;lt;ssl-allowed-ciphers&amp;gt;ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:  RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS&amp;lt;/ssl-allowed-ciphers&amp;gt;&lt;br /&gt;
          &amp;lt;alias source=&amp;quot;/&amp;quot; dest=&amp;quot;/index.html&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;/paths&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If you have used the config file of this documentation, then icecast will be reachable both on &amp;lt;code&amp;gt;http://stream.domain.tld:8000&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;https://stream.domain.tld:port&amp;lt;/code&amp;gt;. You may want to keep it like that as some clients (both for listening and emitting) do not support TLS/SSL. If you want enforce TLS/SSL, you can adjust your config file so that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;listen-socket&amp;gt;&lt;br /&gt;
            &amp;lt;port&amp;gt;999&amp;lt;/port&amp;gt;&lt;br /&gt;
            &amp;lt;ssl&amp;gt;1&amp;lt;/ssl&amp;gt;&lt;br /&gt;
    &amp;lt;/listen-socket&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moar Cores! ===&lt;br /&gt;
In &amp;lt;code&amp;gt;icecast-kh&amp;lt;/code&amp;gt; it&#039;s possible to choose how many threads to use for processing clients. This should be based on the number of CPUs or cores. This can be adjusted in &amp;lt;code&amp;gt;icecast.xml&amp;lt;/code&amp;gt; with the following line inside &amp;lt;code&amp;gt;&amp;lt;limits&amp;gt;&amp;lt;/code&amp;gt;:&lt;br /&gt;
 &amp;lt;workers&amp;gt;4&amp;lt;/workers&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Relaying an External Stream (the lazy way) ===&lt;br /&gt;
This can be done simply by just pointing to the stream you want to relay. Careful though, you need to point to the remote server IP, not the domain. If you add &amp;lt;code&amp;gt;&amp;lt;on-demand&amp;gt;&amp;lt;/code&amp;gt;, the stream will be relayed only if it is requested.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;relay&amp;gt;&lt;br /&gt;
        &amp;lt;server&amp;gt;10.10.10.10&amp;lt;/server&amp;gt;&lt;br /&gt;
        &amp;lt;port&amp;gt;1234&amp;lt;/port&amp;gt;&lt;br /&gt;
        &amp;lt;mount&amp;gt;/blabla.mp3&amp;lt;/mount&amp;gt;&lt;br /&gt;
        &amp;lt;local-mount&amp;gt;/blabla.mp3&amp;lt;/local-mount&amp;gt;&lt;br /&gt;
        &amp;lt;on-demand&amp;gt;1&amp;lt;/on-demand&amp;gt;&lt;br /&gt;
        &amp;lt;relay-shoutcast-metadata&amp;gt;0&amp;lt;/relay-shoutcast-metadata&amp;gt;&lt;br /&gt;
    &amp;lt;/relay&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Streaming]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=623</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=623"/>
		<updated>2024-06-16T18:48:47Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* tweaks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what&#039;s running in the background.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which visible hotspot I want to connect to&lt;br /&gt;
* once selected and if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* however if the Wi-Fi hotspot is unknown, the COMPUTAR shall kindly ask me for the password, and if I agree to fulfill this request, the COMPUTAR shall save it, and proceed to connect to the hotspot&lt;br /&gt;
* Oh no. I am now connected with more COMPUTARS&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;. This is needed to prevent wpa_supplicant to :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;La Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The shell script ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
W_IF=&amp;quot;wlp2s0&amp;quot;  # change with your right interface&lt;br /&gt;
WPA_CONF=&amp;quot;/etc/wpa_supplicant/wpa_supplicant.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# bogus call of sudo to force auth so as to not be bothered by fzf blocking&lt;br /&gt;
# the prompt later on.&lt;br /&gt;
# assumes that you&#039;re not being prompt for passwd at every single call :)&lt;br /&gt;
sudo echo -n&lt;br /&gt;
&lt;br /&gt;
# with a little help from my friends&lt;br /&gt;
get_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ESSID=$(sudo iw ${W_IF} scan | rg &amp;quot;\tSSID&amp;quot; | \&lt;br /&gt;
    sed -e &#039;s/^.*SSID: //g&#039; | sort | uniq | fzf )&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
known_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ID=$(wpa_cli list_networks | rg -F &amp;quot;${ESSID}&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
connect_essid ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;${ESSID} found, connecting...&amp;quot;&lt;br /&gt;
  echo&lt;br /&gt;
  wpa_cli enable_network ${ID}&lt;br /&gt;
  # uncomment following if using with wpa-conf&lt;br /&gt;
  #echo&lt;br /&gt;
  #sudo dhclient -v ${W_IF}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_essid ()&lt;br /&gt;
{&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;password plz&amp;quot;&lt;br /&gt;
    read ESSID_PASSWD&lt;br /&gt;
    while true&lt;br /&gt;
    do&lt;br /&gt;
      echo &amp;quot;is \&amp;quot;${ESSID_PASSWD}\&amp;quot; correct?&amp;quot;&lt;br /&gt;
      read ANSWER_PASSWD&lt;br /&gt;
      if [ &amp;quot;${ANSWER_PASSWD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
      then&lt;br /&gt;
        sudo sh -c &amp;quot;cat &amp;gt;&amp;gt; /etc/wpa_supplicant/wpa_supplicant.conf&amp;quot; &amp;lt;&amp;lt;-EOF&lt;br /&gt;
	# ${ESSID}&lt;br /&gt;
	network={&lt;br /&gt;
	  ssid=&amp;quot;${ESSID}&amp;quot;&lt;br /&gt;
	  psk=&amp;quot;${ESSID_PASSWD}&amp;quot;&lt;br /&gt;
	  disabled=1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	EOF&lt;br /&gt;
        break&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
  done&lt;br /&gt;
  echo &amp;quot;${ESSID} added, connecting...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Here we go&lt;br /&gt;
#cat ~/bin/fox.txt # aesthetics&lt;br /&gt;
get_essid&lt;br /&gt;
if known_essid&lt;br /&gt;
then&lt;br /&gt;
  connect_essid&lt;br /&gt;
  break&lt;br /&gt;
else&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;dunno, add?&amp;quot;&lt;br /&gt;
    read ANSWER_ADD&lt;br /&gt;
    if [ &amp;quot;${ANSWER_ADD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
    then&lt;br /&gt;
      add_essid&lt;br /&gt;
      wpa_cli reconfigure&lt;br /&gt;
      known_essid&lt;br /&gt;
      connect_essid&lt;br /&gt;
      break&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;br /&gt;
&lt;br /&gt;
This setup makes use of the &amp;lt;code&amp;gt;wpa-roam&amp;lt;/code&amp;gt; feature of &amp;lt;code&amp;gt;wpa_action&amp;lt;/code&amp;gt; under Debian. This means that once connected to an hotspot, the underlying network system will under certain circumstances hop to another access point of the same name/type and, if needed, renegotiate a new IP. Why? Well as the word roam implies, this is handy if you are moving around a building with a bunch of access points all serving the same SSID. If this is not acceptable for whatever reasons, it&#039;s possible to prevent this behavior and be connected only to the hotspot/ap you have allowed in the first place. For this you need to edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And because you will loose the automatic IP request negotiation, you need to un-comment in the script the two lines that call &amp;lt;code&amp;gt;dhclient&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;connect_essid ()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Wi-Fi]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=622</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=622"/>
		<updated>2024-06-16T18:46:02Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* How does it work? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what&#039;s running in the background.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which visible hotspot I want to connect to&lt;br /&gt;
* once selected and if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* however if the Wi-Fi hotspot is unknown, the COMPUTAR shall kindly ask me for the password, and if I agree to fulfill this request, the COMPUTAR shall save it, and proceed to connect to the hotspot&lt;br /&gt;
* Oh no. I am now connected with more COMPUTARS&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;. This is needed to prevent wpa_supplicant to :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;La Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The shell script ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
W_IF=&amp;quot;wlp2s0&amp;quot;  # change with your right interface&lt;br /&gt;
WPA_CONF=&amp;quot;/etc/wpa_supplicant/wpa_supplicant.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# bogus call of sudo to force auth so as to not be bothered by fzf blocking&lt;br /&gt;
# the prompt later on.&lt;br /&gt;
# assumes that you&#039;re not being prompt for passwd at every single call :)&lt;br /&gt;
sudo echo -n&lt;br /&gt;
&lt;br /&gt;
# with a little help from my friends&lt;br /&gt;
get_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ESSID=$(sudo iw ${W_IF} scan | rg &amp;quot;\tSSID&amp;quot; | \&lt;br /&gt;
    sed -e &#039;s/^.*SSID: //g&#039; | sort | uniq | fzf )&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
known_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ID=$(wpa_cli list_networks | rg -F &amp;quot;${ESSID}&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
connect_essid ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;${ESSID} found, connecting...&amp;quot;&lt;br /&gt;
  echo&lt;br /&gt;
  wpa_cli enable_network ${ID}&lt;br /&gt;
  # uncomment following if using with wpa-conf&lt;br /&gt;
  #echo&lt;br /&gt;
  #sudo dhclient -v ${W_IF}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_essid ()&lt;br /&gt;
{&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;password plz&amp;quot;&lt;br /&gt;
    read ESSID_PASSWD&lt;br /&gt;
    while true&lt;br /&gt;
    do&lt;br /&gt;
      echo &amp;quot;is \&amp;quot;${ESSID_PASSWD}\&amp;quot; correct?&amp;quot;&lt;br /&gt;
      read ANSWER_PASSWD&lt;br /&gt;
      if [ &amp;quot;${ANSWER_PASSWD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
      then&lt;br /&gt;
        sudo sh -c &amp;quot;cat &amp;gt;&amp;gt; /etc/wpa_supplicant/wpa_supplicant.conf&amp;quot; &amp;lt;&amp;lt;-EOF&lt;br /&gt;
	# ${ESSID}&lt;br /&gt;
	network={&lt;br /&gt;
	  ssid=&amp;quot;${ESSID}&amp;quot;&lt;br /&gt;
	  psk=&amp;quot;${ESSID_PASSWD}&amp;quot;&lt;br /&gt;
	  disabled=1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	EOF&lt;br /&gt;
        break&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
  done&lt;br /&gt;
  echo &amp;quot;${ESSID} added, connecting...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Here we go&lt;br /&gt;
#cat ~/bin/fox.txt # aesthetics&lt;br /&gt;
get_essid&lt;br /&gt;
if known_essid&lt;br /&gt;
then&lt;br /&gt;
  connect_essid&lt;br /&gt;
  break&lt;br /&gt;
else&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;dunno, add?&amp;quot;&lt;br /&gt;
    read ANSWER_ADD&lt;br /&gt;
    if [ &amp;quot;${ANSWER_ADD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
    then&lt;br /&gt;
      add_essid&lt;br /&gt;
      wpa_cli reconfigure&lt;br /&gt;
      known_essid&lt;br /&gt;
      connect_essid&lt;br /&gt;
      break&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;br /&gt;
&lt;br /&gt;
This setup makes use of the &amp;lt;code&amp;gt;wpa-roam&amp;lt;/code&amp;gt; feature of &amp;lt;code&amp;gt;wpa_action&amp;lt;/code&amp;gt; under Debian. This means that once connected to an hotspot, the underlying network system will hop to another access point of the same name/type and if needed renegotiate a new IP. This is handy if you are moving around a building with a bunch of access points all serving the same SSID. If this is not acceptable for whatever reasons, it&#039;s possible to prevent this behavior and be connected only to the hotspot/ap you have allowed in the first place. For this you need to edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And because you will loose the automatic IP request negotiation, you need to un-comment in the script the two lines that call &amp;lt;code&amp;gt;dhclient&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;connect_essid ()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Wi-Fi]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Category:Wi-Fi&amp;diff=621</id>
		<title>Category:Wi-Fi</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Category:Wi-Fi&amp;diff=621"/>
		<updated>2024-06-16T18:42:02Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=620</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=620"/>
		<updated>2024-06-16T18:41:33Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what&#039;s running in the background.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, the COMPUTAR shall ask for the password, save it, and connect to the hotspot&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;. This is needed to prevent wpa_supplicant to :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;La Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The shell script ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
W_IF=&amp;quot;wlp2s0&amp;quot;  # change with your right interface&lt;br /&gt;
WPA_CONF=&amp;quot;/etc/wpa_supplicant/wpa_supplicant.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# bogus call of sudo to force auth so as to not be bothered by fzf blocking&lt;br /&gt;
# the prompt later on.&lt;br /&gt;
# assumes that you&#039;re not being prompt for passwd at every single call :)&lt;br /&gt;
sudo echo -n&lt;br /&gt;
&lt;br /&gt;
# with a little help from my friends&lt;br /&gt;
get_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ESSID=$(sudo iw ${W_IF} scan | rg &amp;quot;\tSSID&amp;quot; | \&lt;br /&gt;
    sed -e &#039;s/^.*SSID: //g&#039; | sort | uniq | fzf )&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
known_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ID=$(wpa_cli list_networks | rg -F &amp;quot;${ESSID}&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
connect_essid ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;${ESSID} found, connecting...&amp;quot;&lt;br /&gt;
  echo&lt;br /&gt;
  wpa_cli enable_network ${ID}&lt;br /&gt;
  # uncomment following if using with wpa-conf&lt;br /&gt;
  #echo&lt;br /&gt;
  #sudo dhclient -v ${W_IF}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_essid ()&lt;br /&gt;
{&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;password plz&amp;quot;&lt;br /&gt;
    read ESSID_PASSWD&lt;br /&gt;
    while true&lt;br /&gt;
    do&lt;br /&gt;
      echo &amp;quot;is \&amp;quot;${ESSID_PASSWD}\&amp;quot; correct?&amp;quot;&lt;br /&gt;
      read ANSWER_PASSWD&lt;br /&gt;
      if [ &amp;quot;${ANSWER_PASSWD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
      then&lt;br /&gt;
        sudo sh -c &amp;quot;cat &amp;gt;&amp;gt; /etc/wpa_supplicant/wpa_supplicant.conf&amp;quot; &amp;lt;&amp;lt;-EOF&lt;br /&gt;
	# ${ESSID}&lt;br /&gt;
	network={&lt;br /&gt;
	  ssid=&amp;quot;${ESSID}&amp;quot;&lt;br /&gt;
	  psk=&amp;quot;${ESSID_PASSWD}&amp;quot;&lt;br /&gt;
	  disabled=1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	EOF&lt;br /&gt;
        break&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
  done&lt;br /&gt;
  echo &amp;quot;${ESSID} added, connecting...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Here we go&lt;br /&gt;
#cat ~/bin/fox.txt # aesthetics&lt;br /&gt;
get_essid&lt;br /&gt;
if known_essid&lt;br /&gt;
then&lt;br /&gt;
  connect_essid&lt;br /&gt;
  break&lt;br /&gt;
else&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;dunno, add?&amp;quot;&lt;br /&gt;
    read ANSWER_ADD&lt;br /&gt;
    if [ &amp;quot;${ANSWER_ADD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
    then&lt;br /&gt;
      add_essid&lt;br /&gt;
      wpa_cli reconfigure&lt;br /&gt;
      known_essid&lt;br /&gt;
      connect_essid&lt;br /&gt;
      break&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;br /&gt;
&lt;br /&gt;
This setup makes use of the &amp;lt;code&amp;gt;wpa-roam&amp;lt;/code&amp;gt; feature of &amp;lt;code&amp;gt;wpa_action&amp;lt;/code&amp;gt; under Debian. This means that once connected to an hotspot, the underlying network system will hop to another access point of the same name/type and if needed renegotiate a new IP. This is handy if you are moving around a building with a bunch of access points all serving the same SSID. If this is not acceptable for whatever reasons, it&#039;s possible to prevent this behavior and be connected only to the hotspot/ap you have allowed in the first place. For this you need to edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And because you will loose the automatic IP request negotiation, you need to un-comment in the script the two lines that call &amp;lt;code&amp;gt;dhclient&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;connect_essid ()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Wi-Fi]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=619</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=619"/>
		<updated>2024-06-16T18:41:07Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what&#039;s running in the background.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, the COMPUTAR shall ask for the password, save it, and connect to the hotspot&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;. This is needed to prevent wpa_supplicant to :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;La Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The shell script ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
W_IF=&amp;quot;wlp2s0&amp;quot;  # change with your right interface&lt;br /&gt;
WPA_CONF=&amp;quot;/etc/wpa_supplicant/wpa_supplicant.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# bogus call of sudo to force auth so as to not be bothered by fzf blocking&lt;br /&gt;
# the prompt later on.&lt;br /&gt;
# assumes that you&#039;re not being prompt for passwd at every single call :)&lt;br /&gt;
sudo echo -n&lt;br /&gt;
&lt;br /&gt;
# with a little help from my friends&lt;br /&gt;
get_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ESSID=$(sudo iw ${W_IF} scan | rg &amp;quot;\tSSID&amp;quot; | \&lt;br /&gt;
    sed -e &#039;s/^.*SSID: //g&#039; | sort | uniq | fzf )&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
known_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ID=$(wpa_cli list_networks | rg -F &amp;quot;${ESSID}&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
connect_essid ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;${ESSID} found, connecting...&amp;quot;&lt;br /&gt;
  echo&lt;br /&gt;
  wpa_cli enable_network ${ID}&lt;br /&gt;
  # uncomment following if using with wpa-conf&lt;br /&gt;
  #echo&lt;br /&gt;
  #sudo dhclient -v ${W_IF}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_essid ()&lt;br /&gt;
{&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;password plz&amp;quot;&lt;br /&gt;
    read ESSID_PASSWD&lt;br /&gt;
    while true&lt;br /&gt;
    do&lt;br /&gt;
      echo &amp;quot;is \&amp;quot;${ESSID_PASSWD}\&amp;quot; correct?&amp;quot;&lt;br /&gt;
      read ANSWER_PASSWD&lt;br /&gt;
      if [ &amp;quot;${ANSWER_PASSWD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
      then&lt;br /&gt;
        sudo sh -c &amp;quot;cat &amp;gt;&amp;gt; /etc/wpa_supplicant/wpa_supplicant.conf&amp;quot; &amp;lt;&amp;lt;-EOF&lt;br /&gt;
	# ${ESSID}&lt;br /&gt;
	network={&lt;br /&gt;
	  ssid=&amp;quot;${ESSID}&amp;quot;&lt;br /&gt;
	  psk=&amp;quot;${ESSID_PASSWD}&amp;quot;&lt;br /&gt;
	  disabled=1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	EOF&lt;br /&gt;
        break&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
  done&lt;br /&gt;
  echo &amp;quot;${ESSID} added, connecting...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Here we go&lt;br /&gt;
#cat ~/bin/fox.txt # aesthetics&lt;br /&gt;
get_essid&lt;br /&gt;
if known_essid&lt;br /&gt;
then&lt;br /&gt;
  connect_essid&lt;br /&gt;
  break&lt;br /&gt;
else&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;dunno, add?&amp;quot;&lt;br /&gt;
    read ANSWER_ADD&lt;br /&gt;
    if [ &amp;quot;${ANSWER_ADD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
    then&lt;br /&gt;
      add_essid&lt;br /&gt;
      wpa_cli reconfigure&lt;br /&gt;
      known_essid&lt;br /&gt;
      connect_essid&lt;br /&gt;
      break&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;br /&gt;
&lt;br /&gt;
This setup makes use of the &amp;lt;code&amp;gt;wpa-roam&amp;lt;/code&amp;gt; feature of &amp;lt;code&amp;gt;wpa_action&amp;lt;/code&amp;gt; under Debian. This means that once connected to an hotspot, the underlying network system will hop to another access point of the same name/type and if needed renegotiate a new IP. This is handy if you are moving around a building with a bunch of access points all serving the same SSID. If this is not acceptable for whatever reasons, it&#039;s possible to prevent this behavior and be connected only to the hotspot/ap you have allowed in the first place. For this you need to edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And because you will loose the automatic IP request negotiation, you need to un-comment in the script the two lines that call &amp;lt;code&amp;gt;dhclient&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;connect_essid ()&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=618</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=618"/>
		<updated>2024-06-16T18:20:54Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands. Why would you do this? I dunno, aesthetics, religious beliefs, limited resources, or just an opportunity to better understand what&#039;s running in the background.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, the COMPUTAR shall ask for the password, save it, and connect to the hotspot&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit the &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; file manually. My rationale is that I need to do this so rarely, that quickly editing a file with a lot of obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case. YMMV :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;. This is needed to prevent wpa_supplicant to :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;La Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The shell script ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
set -e&lt;br /&gt;
&lt;br /&gt;
W_IF=&amp;quot;wlp2s0&amp;quot;  # change with your right interface&lt;br /&gt;
WPA_CONF=&amp;quot;/etc/wpa_supplicant/wpa_supplicant.conf&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# bogus call of sudo to force auth so as to not be bothered by fzf blocking&lt;br /&gt;
# the prompt later on.&lt;br /&gt;
# assumes that you&#039;re not being prompt for passwd at every single call :)&lt;br /&gt;
sudo echo -n&lt;br /&gt;
&lt;br /&gt;
# with a little help from my friends&lt;br /&gt;
get_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ESSID=$(sudo iw ${W_IF} scan | rg &amp;quot;\tSSID&amp;quot; | \&lt;br /&gt;
    sed -e &#039;s/^.*SSID: //g&#039; | sort | uniq | fzf )&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
known_essid ()&lt;br /&gt;
{&lt;br /&gt;
  ID=$(wpa_cli list_networks | rg -F &amp;quot;${ESSID}&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
connect_essid ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;${ESSID} found, connecting...&amp;quot;&lt;br /&gt;
  echo&lt;br /&gt;
  wpa_cli enable_network ${ID}&lt;br /&gt;
  # uncomment following if using with wpa-run&lt;br /&gt;
  #echo&lt;br /&gt;
  #sudo dhclient -v ${W_IF}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
add_essid ()&lt;br /&gt;
{&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;password plz&amp;quot;&lt;br /&gt;
    read ESSID_PASSWD&lt;br /&gt;
    while true&lt;br /&gt;
    do&lt;br /&gt;
      echo &amp;quot;is \&amp;quot;${ESSID_PASSWD}\&amp;quot; correct?&amp;quot;&lt;br /&gt;
      read ANSWER_PASSWD&lt;br /&gt;
      if [ &amp;quot;${ANSWER_PASSWD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
      then&lt;br /&gt;
        sudo sh -c &amp;quot;cat &amp;gt;&amp;gt; /etc/wpa_supplicant/wpa_supplicant.conf&amp;quot; &amp;lt;&amp;lt;-EOF&lt;br /&gt;
	# ${ESSID}&lt;br /&gt;
	network={&lt;br /&gt;
	  ssid=&amp;quot;${ESSID}&amp;quot;&lt;br /&gt;
	  psk=&amp;quot;${ESSID_PASSWD}&amp;quot;&lt;br /&gt;
	  disabled=1&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	EOF&lt;br /&gt;
        break&lt;br /&gt;
      fi&lt;br /&gt;
    done&lt;br /&gt;
    break&lt;br /&gt;
  done&lt;br /&gt;
  echo &amp;quot;${ESSID} added, connecting...&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Here we go&lt;br /&gt;
#cat ~/bin/fox.txt # aesthetics&lt;br /&gt;
get_essid&lt;br /&gt;
if known_essid&lt;br /&gt;
then&lt;br /&gt;
  connect_essid&lt;br /&gt;
  break&lt;br /&gt;
else&lt;br /&gt;
  while true&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;dunno, add?&amp;quot;&lt;br /&gt;
    read ANSWER_ADD&lt;br /&gt;
    if [ &amp;quot;${ANSWER_ADD}&amp;quot; = &amp;quot;y&amp;quot; ]&lt;br /&gt;
    then&lt;br /&gt;
      add_essid&lt;br /&gt;
      wpa_cli reconfigure&lt;br /&gt;
      known_essid&lt;br /&gt;
      connect_essid&lt;br /&gt;
      break&lt;br /&gt;
    fi&lt;br /&gt;
  done&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=617</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=617"/>
		<updated>2024-06-16T17:11:42Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, the COMPUTAR shall ask for the password, save it, and connect to the hotspot&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; manually. The rationale is that I need this so rarely needed, that quickly editing a file with obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
If you start from scratch the only thing you need in this file is this:&lt;br /&gt;
 ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev&lt;br /&gt;
&lt;br /&gt;
If you already have some entries listed (in case you have been using a wifi network manager), make sure to disable each network with &amp;lt;code&amp;gt;disabled=1&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Settings for my nice network&lt;br /&gt;
network={&lt;br /&gt;
  ssid=&amp;quot;Compagnie Créole&amp;quot;&lt;br /&gt;
  psk=&amp;quot;AU BAL AU BAL MASQUÉ OHÉ OHÉ&amp;quot;&lt;br /&gt;
  disabled=1&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=616</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=616"/>
		<updated>2024-06-16T16:51:30Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Use case */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTAR which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, the COMPUTAR shall connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, the COMPUTAR shall ask for the password, save it, and connect to the hotspot&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; manually. The rationale is that I need this so rarely needed, that quickly editing a file with obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=615</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=615"/>
		<updated>2024-06-16T16:48:46Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Config and script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTER which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, ask for the password, save it, and connect to it&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; manually. The rationale is that I need this so rarely needed, that quickly editing a file with obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and adjust to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== tweaks ==&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=614</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=614"/>
		<updated>2024-06-16T16:43:49Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* How does it work? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTER which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, ask for the password, save it, and connect to it&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; manually. The rationale is that I need this so rarely needed, that quickly editing a file with obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case :)&lt;br /&gt;
&lt;br /&gt;
== Config and script ==&lt;br /&gt;
=== &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; and tweak according to your network name (here wlp2s0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
auto wlp2s0&lt;br /&gt;
iface wlp2s0 inet manual&lt;br /&gt;
  wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf&lt;br /&gt;
iface default inet dhcp&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== tweaks ===&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=613</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=613"/>
		<updated>2024-06-16T16:35:09Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
== How does it work? ==&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;br /&gt;
&lt;br /&gt;
=== Use case ===&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTER which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, ask for the password, save it, and connect to it&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; if the Wi-Fi hotspot needs to be configured with specific settings (for instance for specific key management settings of for open networks), it is necessary to edit &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; manually. The rationale is that I need this so rarely needed, that quickly editing a file with obscure settings outweighs by far the need to make a more complicated shell script to handle such corner case :)&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=612</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=612"/>
		<updated>2024-06-16T16:24:45Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* The things that mater */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTER which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, ask for the password, save it, and connect to it&lt;br /&gt;
&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/network/interfaces&amp;lt;/code&amp;gt; — network interface configuration for ifup and ifdown&lt;br /&gt;
* &amp;lt;code&amp;gt;iw&amp;lt;/code&amp;gt; — show/manipulate wireless devices and their configuration&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_cli&amp;lt;/code&amp;gt; — WPA command line client&lt;br /&gt;
* &amp;lt;code&amp;gt;wpa_supplicant&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;wpa_supplicant.conf&amp;lt;/code&amp;gt; —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* &amp;lt;code&amp;gt;fzf&amp;lt;/code&amp;gt; — command line fuzzy finder&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=611</id>
		<title>Minimal TUI Wi-Fi Manager</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Minimal_TUI_Wi-Fi_Manager&amp;diff=611"/>
		<updated>2024-06-16T16:22:55Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created page with &amp;quot;Good news! If you don&amp;#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&amp;#039;t worry, Linux has all the...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Good news! If you don&#039;t want to install third party daemons, gooey GUI things, or bloat just so you can connect to a wireless access point, then don&#039;t worry, Linux has all the CLI tools necessary to create a minimal on-demand TUI shell script thing to connect to, and manage these very Wi-Fi connections. The following info is for Debian, however the approach will be the same for other distros, including BSD operating systems that will differ mostly for some of the network commands.&lt;br /&gt;
&lt;br /&gt;
The use case here is as follow:&lt;br /&gt;
* don&#039;t connect to a Wi-Fi hotspot unless I explicitly ask the COMPUTAR to do so&lt;br /&gt;
* if I need to connect to a Wi-Fi hotspot, the COMPUTAR should give me a list of the visible ones&lt;br /&gt;
* a user-friendly™ interface with fuzzy search should help me tell the COMPUTER which hotspot I want to connect to&lt;br /&gt;
* if the Wi-Fi hotspot is already known, connect to it&lt;br /&gt;
* if the Wi-Fi hotspot is unknown, ask for the password, save it, and connect to it&lt;br /&gt;
&lt;br /&gt;
=== The things that mater ===&lt;br /&gt;
&lt;br /&gt;
* `/etc/network/interfaces` — network interface configuration for ifup and ifdown&lt;br /&gt;
* `iw` — show/manipulate wireless devices and their configuration&lt;br /&gt;
* `wpa_cli` — WPA command line client&lt;br /&gt;
* `wpa_supplicant` and `wpa_supplicant.conf` —  Wi-Fi Protected Access client and IEEE 802.1X supplicant and its configuration file&lt;br /&gt;
* `fzf` — command line fuzzy finder&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=610</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=610"/>
		<updated>2024-05-02T22:16:36Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Waymo.webp|right|512px]]&lt;br /&gt;
&#039;&#039;&#039;Welcome to RUN YOUR OWN, the wiki documentation of LURK&#039;s servers.&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
One of LURK&#039;s mission is to make sure we&#039;re not creating yet another silo for online discussions and publishing, but also give enough inspiration for others to do the same and start provide their own centralised, decentralised, federated, and whatnot services.&lt;br /&gt;
&lt;br /&gt;
Running your own server, and its services, is not always straightforward, so this is why we are using this space to document and make public how we maintain and configure LURK servers (as well as some of the machines we use).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;This documentation effort is an ongoing process, we add stuff as we develop the environment, and learn more about it ourselves.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Server Documents ==&lt;br /&gt;
&lt;br /&gt;
{{Special:AllPages|namespace=14}}&lt;br /&gt;
* [[TODO]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Firewall&amp;diff=609</id>
		<title>Firewall</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Firewall&amp;diff=609"/>
		<updated>2024-05-02T22:14:50Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* iptables oneliners */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Different ways to handle &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Using &amp;lt;code&amp;gt;iptables-persistent&amp;lt;/code&amp;gt; on Debian ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; In use on &amp;lt;code&amp;gt;vrijdagmiddagborrel&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It&#039;s basically a set of &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt; plugins for &amp;lt;code&amp;gt;netfilter-persistent&amp;lt;/code&amp;gt;, which itself is a loader for different netfilter configuration. Once installed, it will take care of restoring rules at boot time, and through a small helper, can be used to reload/update/save rules on the fly.&lt;br /&gt;
&lt;br /&gt;
=== Installation and config ===&lt;br /&gt;
* Installation:&lt;br /&gt;
 apt install iptables-persistent netfilter-persistent&lt;br /&gt;
* Add/change iptables rules located at &amp;lt;code&amp;gt;/etc/iptables/rules.v4&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/etc/iptables/rules.v6&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
* Apply new rules after changes made to &amp;lt;code&amp;gt;rules.v*&amp;lt;/code&amp;gt; files and check result&lt;br /&gt;
 netfilter-persistent reload&lt;br /&gt;
 iptables -L&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;iptables&amp;lt;/code&amp;gt; oneliners ==&lt;br /&gt;
* list all rules from all chains&lt;br /&gt;
 iptables -L&lt;br /&gt;
* block an IP&lt;br /&gt;
 iptables -I INPUT -s 192.168.111.111 -j DROP&lt;br /&gt;
 iptables -I OUTPUT -d 192.168.111.111 -j DROP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:System]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=608</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=608"/>
		<updated>2024-05-02T22:13:34Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Waymo.webp|right|512px]]&lt;br /&gt;
&#039;&#039;&#039;Welcome to RUN YOUR OWN, the wiki documentation of LURK&#039;s servers.&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
One of LURK&#039;s mission is to make sure we&#039;re not creating yet another silo for online discussions and publishing, but also give enough inspiration for others to do the same and start provide their own centralised, decentralised, federated, and whatnot services.&lt;br /&gt;
&lt;br /&gt;
Running your own server, and its services, is not always straightforward, so this is why we are using this space to document and make public how we maintain and configure LURK servers (as well as some of the machines we use).&lt;br /&gt;
&lt;br /&gt;
== Request for Feedback ==&lt;br /&gt;
&lt;br /&gt;
This documentation effort is an ongoing process, we add stuff as we develop the environment, and learn more about it ourselves.  We gladly welcome your feedback and comments:&lt;br /&gt;
* Mailing list about LURK: https://we.lurk.org/postorius/lists/metalurk.we.lurk.org&lt;br /&gt;
* Chat about LURK: https://talk.lurk.org/channel/_meta&lt;br /&gt;
&lt;br /&gt;
== Server Documents ==&lt;br /&gt;
&lt;br /&gt;
{{Special:AllPages|namespace=14}}&lt;br /&gt;
* [[TODO]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=607</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Main_Page&amp;diff=607"/>
		<updated>2024-05-02T22:11:57Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Waymo.webp|right]]&lt;br /&gt;
&#039;&#039;&#039;Welcome to RUN YOUR OWN, the wiki documentation of LURK&#039;s servers.&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
One of LURK&#039;s mission is to make sure we&#039;re not creating yet another silo for online discussions and publishing, but also give enough inspiration for others to do the same and start provide their own centralised, decentralised, federated, and whatnot services.&lt;br /&gt;
&lt;br /&gt;
Running your own server, and its services, is not always straightforward, so this is why we are using this space to document and make public how we maintain and configure LURK servers (as well as some of the machines we use).&lt;br /&gt;
&lt;br /&gt;
== Request for Feedback ==&lt;br /&gt;
&lt;br /&gt;
This documentation effort is an ongoing process, we add stuff as we develop the environment, and learn more about it ourselves.  We gladly welcome your feedback and comments:&lt;br /&gt;
* Mailing list about LURK: https://we.lurk.org/postorius/lists/metalurk.we.lurk.org&lt;br /&gt;
* Chat about LURK: https://talk.lurk.org/channel/_meta&lt;br /&gt;
&lt;br /&gt;
== Server Documents ==&lt;br /&gt;
&lt;br /&gt;
{{Special:AllPages|namespace=14}}&lt;br /&gt;
* [[TODO]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=File:Waymo.webp&amp;diff=606</id>
		<title>File:Waymo.webp</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=File:Waymo.webp&amp;diff=606"/>
		<updated>2024-05-02T22:11:21Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Category:Maintenance&amp;diff=605</id>
		<title>Category:Maintenance</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Category:Maintenance&amp;diff=605"/>
		<updated>2024-04-05T13:59:13Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Uninstall_systemd_services&amp;diff=604</id>
		<title>Uninstall systemd services</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Uninstall_systemd_services&amp;diff=604"/>
		<updated>2024-04-05T13:59:04Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
systemctl stop [servicename]&lt;br /&gt;
systemctl disable [servicename]&lt;br /&gt;
rm /etc/systemd/system/[servicename]&lt;br /&gt;
rm /etc/systemd/system/[servicename] # and symlinks that might be related&lt;br /&gt;
rm /usr/lib/systemd/system/[servicename] &lt;br /&gt;
rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related&lt;br /&gt;
systemctl daemon-reload&lt;br /&gt;
systemctl reset-failed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category: Maintenance]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Uninstall_systemd_services&amp;diff=603</id>
		<title>Uninstall systemd services</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Uninstall_systemd_services&amp;diff=603"/>
		<updated>2024-04-05T13:58:27Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created page with &amp;quot;&amp;lt;pre&amp;gt; systemctl stop [servicename] systemctl disable [servicename] rm /etc/systemd/system/[servicename] rm /etc/systemd/system/[servicename] # and symlinks that might be relat...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
systemctl stop [servicename]&lt;br /&gt;
systemctl disable [servicename]&lt;br /&gt;
rm /etc/systemd/system/[servicename]&lt;br /&gt;
rm /etc/systemd/system/[servicename] # and symlinks that might be related&lt;br /&gt;
rm /usr/lib/systemd/system/[servicename] &lt;br /&gt;
rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related&lt;br /&gt;
systemctl daemon-reload&lt;br /&gt;
systemctl reset-failed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Cleanup&amp;diff=602</id>
		<title>Cleanup</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Cleanup&amp;diff=602"/>
		<updated>2024-04-04T05:32:08Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created page with &amp;quot;Sometimes you need to cleanup. Because there is too much shit on your disks.  === general cruft === &amp;lt;code&amp;gt;ncdu&amp;lt;/code&amp;gt; is your friend. &amp;lt;code&amp;gt;dust&amp;lt;/code&amp;gt; too.  === log files ===...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sometimes you need to cleanup. Because there is too much shit on your disks.&lt;br /&gt;
&lt;br /&gt;
=== general cruft ===&lt;br /&gt;
&amp;lt;code&amp;gt;ncdu&amp;lt;/code&amp;gt; is your friend. &amp;lt;code&amp;gt;dust&amp;lt;/code&amp;gt; too.&lt;br /&gt;
&lt;br /&gt;
=== log files ===&lt;br /&gt;
==== /var/log ====&lt;br /&gt;
Easy. just &amp;lt;code&amp;gt;rm&amp;lt;/code&amp;gt; compressed archives and the first &amp;lt;code&amp;gt;.1&amp;lt;/code&amp;gt; rotated files. If you are really in emergency mode you can also delete the live log files, they will be recreated, don&#039;t worry.&lt;br /&gt;
&lt;br /&gt;
==== systemd managed logs ====&lt;br /&gt;
For these it&#039;s better to use the dedicated tool:&lt;br /&gt;
 journalctl --disk-usage        # what&#039;s the damage&lt;br /&gt;
 journalctl --vacuum-size=200M  # delete old logs so that current logs only take 10MB disk usage&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Storage]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=601</id>
		<title>Wildcard Certificates with acme.sh</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Wildcard_Certificates_with_acme.sh&amp;diff=601"/>
		<updated>2024-04-02T08:27:23Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Using acme.sh ==&lt;br /&gt;
&lt;br /&gt;
Since the certbot gandi dns plugin has been giving issues over the past months (no smooth renewal, leading to unavailability of sites) we started moving things to acme.sh. Seems to work better, easier to setup etc.&lt;br /&gt;
&lt;br /&gt;
=== Install the bash script ===&lt;br /&gt;
&lt;br /&gt;
 wget https://get.acme.sh &lt;br /&gt;
&lt;br /&gt;
As root:&lt;br /&gt;
&lt;br /&gt;
 sh acme.sh&lt;br /&gt;
&lt;br /&gt;
This will install the script to /root/ and add it to path &lt;br /&gt;
&lt;br /&gt;
=== Request a wildcard cert for lurk.org ===&lt;br /&gt;
&lt;br /&gt;
first find and export the gandi dns key:&lt;br /&gt;
&lt;br /&gt;
 export GANDI_LIVEDNS_KEY=&amp;quot;fdmlfsdklmfdkmqsdfk&amp;quot; &lt;br /&gt;
&lt;br /&gt;
Then request a wildcard cert. (the dns key is added to a config file automatically for future renewals)&lt;br /&gt;
&lt;br /&gt;
 acme.sh --issue --dns dns_gandi_livedns --nginx -d *.lurk.org&lt;br /&gt;
&lt;br /&gt;
Find the certs in:&lt;br /&gt;
&lt;br /&gt;
 /root/.acme.sh/\*.lurk.org/&lt;br /&gt;
&lt;br /&gt;
== Migration status ==&lt;br /&gt;
&lt;br /&gt;
Done: &lt;br /&gt;
&lt;br /&gt;
* VMB (nginx, masto, icecast)&lt;br /&gt;
&lt;br /&gt;
To do:&lt;br /&gt;
&lt;br /&gt;
* agnes (nginx, prosody, mm3)&lt;br /&gt;
* douglas (???)&lt;br /&gt;
&lt;br /&gt;
== Ref ==&lt;br /&gt;
&lt;br /&gt;
* https://forums.freebsd.org/threads/howto-ssl-tls-certificates-with-acme-sh.61231/ (FreeBSD)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= N.B. everything below is for archival reference =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Base installation ==&lt;br /&gt;
&lt;br /&gt;
 apt install python-pip&lt;br /&gt;
 pip install wheel&lt;br /&gt;
 pip install certbot&lt;br /&gt;
&lt;br /&gt;
== DNS plugins ==&lt;br /&gt;
=== Gandi ===&lt;br /&gt;
&#039;&#039;&#039;NOTE: At time of writing, only an API key from the domain owner will work. So another account, even if listed technical contact, will not able to use the live DNS API, just the live DNS web interface. Since the writing of this HOWTO, there is now this as well https://github.com/obynio/certbot-plugin-gandi TODO&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Get API key from Gandi (somewhere in account settings)&lt;br /&gt;
* install certbot-plugin-gandi&lt;br /&gt;
 pip install &#039;git+https://gitlab.com/cspublic/certbot-plugin-gandi.git&#039;&lt;br /&gt;
 mkdir /etc/certbot-plugin-gandi&lt;br /&gt;
* create /etc/certbot-plugin-gandi/gandi.ini with the following:&lt;br /&gt;
 certbot_plugin_gandi:dns_api_key=APIKEY&lt;br /&gt;
* a bit of paranoia&lt;br /&gt;
 chmod 600 /etc/certbot-plugin-gandi/gandi.ini&lt;br /&gt;
* request certificate for both mydomain.blabla &#039;&#039;&#039;and&#039;&#039;&#039; *.mydomain.blabla&lt;br /&gt;
&#039;&#039;&#039;NOTE: At time of writing, the default sever end point used by cerbot (0.22) is not compatible with ACME v2, as a workaround --server must be passed manually. Next version of certbot should point to the right server&#039;&#039;&#039;&lt;br /&gt;
 /usr/local/bin/certbot certonly -a certbot-plugin-gandi:dns --certbot-plugin-gandi:dns-credentials /etc/certbot-plugin-gandi/gandi.ini -d mydomain.blabla -d *.mydomain.blabla --server https://acme-v02.api.letsencrypt.org/directory&lt;br /&gt;
* If all goes well certs will be there:&lt;br /&gt;
&#039;&#039;&#039;NOTE: At time of writing, certbot-plugin-gandi seems to behave a bit funnily when asked to request a challenge for a wildcard cert (it works flawslessly for regular domains). It might be needed to run the command several times to get the infamous CONGRATULATION message from certbot.&#039;&#039;&#039;&lt;br /&gt;
 /etc/letsencrypt/live/mydomain.blabla/fullchain.pem&lt;br /&gt;
 /etc/letsencrypt/live/mydomain.blabla/privkey.pem&lt;br /&gt;
&lt;br /&gt;
== Renewal ==&lt;br /&gt;
To non-interactively renew *all* of your certificates:&lt;br /&gt;
 /usr/local/bin/certbot renew&lt;br /&gt;
&lt;br /&gt;
=== douglas ===&lt;br /&gt;
=== agnes ===&lt;br /&gt;
&#039;&#039;&#039;TODO: hooks!&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
service nginx restart&lt;br /&gt;
prosodyctl reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Certificates]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Simple_LAN_filesharing_with_WebDAV&amp;diff=600</id>
		<title>Simple LAN filesharing with WebDAV</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Simple_LAN_filesharing_with_WebDAV&amp;diff=600"/>
		<updated>2024-03-18T23:16:18Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Pro Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;WebDAV&#039;&#039;&#039; is both a quite popular and yet overlooked way to access and edit files remotely across a wide range of operating systems. Yes it&#039;s web stuff, again, but surprisingly fast, lightweight, and that can recover quite well on unstable networks or when the server has to be restarted, or has gone for lunch. A reason why it may be overlooked is possibly because it&#039;s often associated with sausage factories like own/nextcloud, or standalone implementations that are not particularly exciting. What is less known is that many web servers come with their own &#039;&#039;&#039;WebDAV&#039;&#039;&#039; implementation. Out of the usual suspects, &#039;&#039;&#039;nginx&#039;&#039;&#039;, &#039;&#039;&#039;Apache&#039;&#039;&#039;, and &#039;&#039;&#039;lighttpd&#039;&#039;&#039;,  the latter has both the most lightweight and most complete implementation. No need for anything else!&lt;br /&gt;
&lt;br /&gt;
In these notes we only cover a simple LAN setup, you can build upon it for more complex use case of course.&lt;br /&gt;
&lt;br /&gt;
== Server side ==&lt;br /&gt;
=== Installation ===&lt;br /&gt;
* This is for Debian, but I know you&#039;re smart, you will figure it out for &amp;lt;code&amp;gt;${FLAVOUR_OF_THE_MONTH_DISTRO}&amp;lt;/code&amp;gt;&lt;br /&gt;
 sudo apt install lighttpd lighttpd-mod-webdav&lt;br /&gt;
&lt;br /&gt;
=== Example Configuration ===&lt;br /&gt;
Basically the configuration that matters for now are in &amp;lt;code&amp;gt;/etc/lighttpd/conf-available&amp;lt;/code&amp;gt; and with symlinks in &amp;lt;code&amp;gt;/etc/lighttpd/conf-enabled&amp;lt;/code&amp;gt;. &#039;&#039;&#039;In our simple example we will have three shared folders, one that can be mounted read-only by anyone, and two that are read-write but require a username and password&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* By default a temp config file called &amp;lt;code&amp;gt;99-unconfigured.conf&amp;lt;/code&amp;gt; provides a generic landing page. We don&#039;t need it and we just have to enable the authentication config.&lt;br /&gt;
 sudo lighttpd-disable-mod unconfigured&lt;br /&gt;
 sudo lighttpd-enable-mod auth&lt;br /&gt;
* Create a user and password for the read-write share&lt;br /&gt;
 sudo apt install apache2-utils&lt;br /&gt;
 sudo htpasswd -c /etc/lighttpd/user.htpasswd turtleprincess heygirl&lt;br /&gt;
* create a new configuration file &amp;lt;code&amp;gt;/etc/lighttpd/conf-available/66-webdav.conf&amp;lt;/code&amp;gt; with the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server.modules += ( &amp;quot;mod_webdav&amp;quot; )&lt;br /&gt;
dir-listing.encoding = &amp;quot;utf-8&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
# This is needed for keepings tracks of locks and props which&lt;br /&gt;
# are needed for shares that can be edited&lt;br /&gt;
webdav.sqlite-db-name = &amp;quot;/var/cache/lighttpd/lighttpd.webdav.db&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
# auth&lt;br /&gt;
server.modules += (&amp;quot;mod_authn_file&amp;quot;)&lt;br /&gt;
auth.backend = &amp;quot;htpasswd&amp;quot; &lt;br /&gt;
auth.backend.htpasswd.userfile = &amp;quot;/etc/lighttpd/user.htpasswd&amp;quot;&lt;br /&gt;
auth.require = ( &amp;quot;/readwrite1&amp;quot;     =&amp;gt; ( &amp;quot;method&amp;quot; =&amp;gt; &amp;quot;basic&amp;quot;, &lt;br /&gt;
                                 &amp;quot;realm&amp;quot; =&amp;gt; &amp;quot;YOU WOT MATE&amp;quot;, &lt;br /&gt;
                                 &amp;quot;require&amp;quot; =&amp;gt; &amp;quot;valid-user&amp;quot; ),&lt;br /&gt;
                 &amp;quot;/readwrite2&amp;quot; =&amp;gt; ( &amp;quot;method&amp;quot; =&amp;gt; &amp;quot;basic&amp;quot;,&lt;br /&gt;
                                 &amp;quot;realm&amp;quot; =&amp;gt; &amp;quot;YOU WOT MATE&amp;quot;,&lt;br /&gt;
                                 &amp;quot;require&amp;quot; =&amp;gt; &amp;quot;valid-user&amp;quot; ))&lt;br /&gt;
  &lt;br /&gt;
# read-only stuff&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readonly(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readonly&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readonly&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.is-readonly = &amp;quot;enable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
# shared pit of madness&lt;br /&gt;
# for users listed in /etc/lighttpd/user.htpasswd&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readwrite1(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readwrite1&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readwrite1&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot;&lt;br /&gt;
    webdav.is-readonly = &amp;quot;disable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
$HTTP[&amp;quot;url&amp;quot;] =~ &amp;quot;^/readwrite2(?:/|$)&amp;quot; {&lt;br /&gt;
    alias.url = ( &amp;quot;/readwrite2&amp;quot; =&amp;gt; &amp;quot;/local/path/to/readwrite2&amp;quot; )&lt;br /&gt;
    dir-listing.activate = &amp;quot;enable&amp;quot; &lt;br /&gt;
    webdav.activate = &amp;quot;enable&amp;quot;&lt;br /&gt;
    webdav.is-readonly = &amp;quot;disable&amp;quot; &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now if you wonder what kind of magic will happen so that the lighttpd process, local and remote users can happily live together ever after, and edit the same files, well, none. It won&#039;t happen just like this, it does not work and you will be sad. Then you will start binge drinking to forget about server administration. You will go in the streets, pick up fights with strangers who are in a much better physical condition because they don&#039;t spend hours configuring neovim plugins that &#039;&#039;you haven&#039;t even used once&#039;&#039;. It will be painful. So to avoid this unfortunate situation you need to do two things:&lt;br /&gt;
&lt;br /&gt;
* First, the folder needs to be group-owned by the lighttpd process owner, in our case, on Debian, it&#039;s &amp;lt;code&amp;gt;www-data&amp;lt;/code&amp;gt;. You also need to set the group ID bit on the folder you intend to use as WedDAV share, so that all newly created files will inherit the group ownership of this folder.&lt;br /&gt;
 sudo chown regular_user:www-data /local/path/to/readwrite1&lt;br /&gt;
 sudo chmod g+ws /local/path/to/readwrite1&lt;br /&gt;
* Second, you need to change the way lighttpd is started so that its umask is set in a way that any permission may be set for user and group (default is just user). On a systemd based system (haters gonna hate) you need to edit &amp;lt;code&amp;gt;/etc/systemd/system/lighttpd.service&amp;lt;/code&amp;gt; like this:&lt;br /&gt;
 ExecStart=/bin/sh -c &#039;umask 002;/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf&#039;&lt;br /&gt;
&lt;br /&gt;
That&#039;s it, you have a working simple LAN filesharing with WebDAV check the documentation for more options, and more fun config time, at home, where it&#039;s much safer for you.&lt;br /&gt;
&lt;br /&gt;
== Client side ==&lt;br /&gt;
=== Web browser ===&lt;br /&gt;
The nice advantage of the setup above is that all the files can be readily browsed at the local IP of the machine running lighttpd, for instance http://192.168.100.100/readonly. If you&#039;re into web stuff have a look at https://github.com/dom111/webdav-js, it would be really trivial to serve this js file with the lighttpd server and provide more functionality than just browsing and downloading.&lt;br /&gt;
&lt;br /&gt;
=== Linux filesystem ===&lt;br /&gt;
Mounting a WebDAV on Linux is straightforward with &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; and requires minimal configuration. &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; is also able to recover quite well from disconnections and potential read/write fuckery (there is a daemon and a local cache, but you don&#039;t need to worry about this). If the server is dead, that you need to poweroff your machine, and you still have something mounted, it&#039;s a good idea to unmount things first to speed up shutdown. No it won&#039;t lock like a little NFS shit but there is a timeout and you&#039;re a busy person.&lt;br /&gt;
* To mount manually the read-only folder from above:&lt;br /&gt;
 sudo apt install davfs2&lt;br /&gt;
 sudo mount -t davfs http://192.168.100.100/readonly /mnt/readonly&lt;br /&gt;
* To remember username passwords you can create a personal &amp;lt;code&amp;gt;~/davfs2/secrets&amp;lt;/code&amp;gt; file with:&lt;br /&gt;
 http://192.168.100.100/readwrite1 turtleprincess heygirl&lt;br /&gt;
 http://192.168.100.100/readwrite2 turtleprincess heygirl&lt;br /&gt;
 etc&lt;br /&gt;
* You can also have everything configured in your &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt; and then mount everything as a regular user:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# My cool LAN WebDAV thing&lt;br /&gt;
http://192.168.100.100/readonly    /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
http://192.168.100.100/readwrite1  /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
http://192.168.100.100/readwrite2  /mnt/readonly/    davfs  user,uid=username,noauto  0  0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FreeBSD filesystem ===&lt;br /&gt;
On FreeBSD it&#039;s basically the same as on Linux. lol. Of course not! What did you think? That would be too easy. You need to work hard to earn your condescending smug BSD coolness. At time of writing, &amp;lt;code&amp;gt;davfs2&amp;lt;/code&amp;gt; is being [https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267518 ported to FreeBSD by its author]. Don&#039;t hold your breath, but hopefully this will happen because the FreeBSD usual way to mount WebDAV stuff with &amp;lt;code&amp;gt;mount.webdavfs&amp;lt;/code&amp;gt; just sucks (&amp;quot;Device not configured&amp;quot; on certain reading operations, not able to recover when the server disconnects). As a workaround, the all-you-can-eat-software-buffet &amp;lt;code&amp;gt;rclone&amp;lt;/code&amp;gt; is the only reliable way to have WebDAV mounted in a FreeBSD filesystem.&lt;br /&gt;
&lt;br /&gt;
* installation&lt;br /&gt;
 pkg install rclone # yeah yeah you can use portmaster and disable stuff you will regret later&lt;br /&gt;
* load fuse&lt;br /&gt;
 sudo kldload fusefs&lt;br /&gt;
* to make it permanent add the following to &amp;lt;code&amp;gt;/boot/loader.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 # Filesystems in Userspace&lt;br /&gt;
 fusefs_load=&amp;quot;YES&lt;br /&gt;
* create a &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt; config file with:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[192.168.100.100]&lt;br /&gt;
type = webdav&lt;br /&gt;
url = http://192.168.100.100/&lt;br /&gt;
vendor = other&lt;br /&gt;
user = turtleprincess&lt;br /&gt;
pass = SEE_BELOW&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works&lt;br /&gt;
 sudo mkdir /mnt/readwrite2&lt;br /&gt;
 sudo chown user:user /mnt/readwrite2&lt;br /&gt;
 rclone mount 192.168.100.100:readwrite2 /mnt/readwrite2/ --vfs-cache-mode writes --daemon&lt;br /&gt;
&lt;br /&gt;
You can also make entries in your &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
* rclone can&#039;t really be used directly, so we will trick fuse&lt;br /&gt;
 sudo ln -s /usr/local/bin/rclone /usr/local/bin/mount.rclone&lt;br /&gt;
* in &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# My cool LAN WebDAV thing&lt;br /&gt;
192.168.100.100:readonly     /mnt/readonly    fuse noauto,ro,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
192.168.100.100:readwrite1   /mnt/readwrite1  fuse noauto,rw,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
192.168.100.100:readwrite1   /mnt/readwrite1  fuse noauto,rw,mountprog=/usr/local/bin/mount.rclone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nautilus ===&lt;br /&gt;
For those into GUI (not judging, it&#039;s a free country) WebDAV is really easy to access thanks to the GVfs daemon. It&#039;s also a solid option in terms of recovery and making sure little to no fuckery is possible when writing on an unstable network. In practice, click on the &amp;quot;other&amp;quot; location button on the left pane, choose WedDAV and enter the URL in the form of &amp;lt;code&amp;gt;dav://192.168.100.100/readwrite1&amp;lt;/code&amp;gt; and give your credentials. The only caveat is that the mounted folder name will be the server name, only the server name (IP in this case), so you may want to add your share to the bookmarks, and rename the bookmark to something more meaningful.&lt;br /&gt;
&lt;br /&gt;
=== Android ===&lt;br /&gt;
Several commercial, closed source options. We don&#039;t talk to these people. There are however three interesting FLOSS options:&lt;br /&gt;
* https://github.com/newhinton/Round-Sync - super complete, multiple network file storage supported (based on rclone)&lt;br /&gt;
* https://github.com/phpbg/easysync - minimal automated WebDAV sync for the usual Android user data folders&lt;br /&gt;
* https://github.com/bitfireAT/davx5-ose - focused on CalDAV/CardDAV but hidden in one menu there is a mini browsing option for WebDAV&lt;br /&gt;
&lt;br /&gt;
=== Nintendo Switch ===&lt;br /&gt;
Because you know, reasons:&lt;br /&gt;
* https://github.com/cy33hc/switch-ezremote-client - simple file browser/editor&lt;br /&gt;
* https://github.com/J-D-K/JKSV - popular save file manager, a WebDAV folder can be the default folder to export save backups&lt;br /&gt;
&lt;br /&gt;
== Pro Tips ==&lt;br /&gt;
* IPs are used above but you can use a local DNS or make use of your local &amp;lt;code&amp;gt;/etc/hosts&amp;lt;/code&amp;gt; files to give a nice name to your WedDAV server, look into RFC 8375 for pointers.&lt;br /&gt;
* To debug things if things are not behaving as nice things:&lt;br /&gt;
 lighttpd-enable-mod accesslog&lt;br /&gt;
 systemctl restart lighttpd&lt;br /&gt;
 tail -f /var/log/lighttpd/access.log&lt;br /&gt;
 # 17.4 hours later&lt;br /&gt;
 # Problem solved at last&lt;br /&gt;
 lighttpd-disable-mod accesslog&lt;br /&gt;
 systemctl restart lighttpd&lt;br /&gt;
&lt;br /&gt;
[[Category: WebDAV]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Category:WebDAV&amp;diff=599</id>
		<title>Category:WebDAV</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Category:WebDAV&amp;diff=599"/>
		<updated>2024-03-18T23:15:49Z</updated>

		<summary type="html">&lt;p&gt;320x200: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=598</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=598"/>
		<updated>2024-03-18T23:15:36Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home screen. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then it&#039;s time to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with &amp;quot;:&amp;quot; in their name won&#039;t sync because they can&#039;t be created on an Android fs&lt;br /&gt;
* we can&#039;t use modtime as a criteria for detecting file changes so filesize is the main criteria. We can&#039;t use it because Android does not support this somehow. I&#039;m a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.&lt;br /&gt;
* access to &amp;lt;code&amp;gt;/sdcard&amp;lt;/code&amp;gt; can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again&lt;br /&gt;
* when the script is launched from the home screen it&#039;s nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in &amp;lt;code&amp;gt;.termux/termux.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
 hide-soft-keyboard-on-startup = true&lt;br /&gt;
&lt;br /&gt;
[[Category: WebDAV]]&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=597</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=597"/>
		<updated>2024-03-18T23:12:00Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Preparing the local and remote folders */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home screen. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then it&#039;s time to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with &amp;quot;:&amp;quot; in their name won&#039;t sync because they can&#039;t be created on an Android fs&lt;br /&gt;
* we can&#039;t use modtime as a criteria for detecting file changes so filesize is the main criteria. We can&#039;t use it because Android does not support this somehow. I&#039;m a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.&lt;br /&gt;
* access to &amp;lt;code&amp;gt;/sdcard&amp;lt;/code&amp;gt; can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again&lt;br /&gt;
* when the script is launched from the home screen it&#039;s nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in &amp;lt;code&amp;gt;.termux/termux.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
 hide-soft-keyboard-on-startup = true&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=596</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=596"/>
		<updated>2024-03-18T23:05:49Z</updated>

		<summary type="html">&lt;p&gt;320x200: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home screen. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with &amp;quot;:&amp;quot; in their name won&#039;t sync because they can&#039;t be created on an Android fs&lt;br /&gt;
* we can&#039;t use modtime as a criteria for detecting file changes so filesize is the main criteria. We can&#039;t use it because Android does not support this somehow. I&#039;m a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.&lt;br /&gt;
* access to &amp;lt;code&amp;gt;/sdcard&amp;lt;/code&amp;gt; can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again&lt;br /&gt;
* when the script is launched from the home screen it&#039;s nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in &amp;lt;code&amp;gt;.termux/termux.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
 hide-soft-keyboard-on-startup = true&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=595</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=595"/>
		<updated>2024-03-18T23:05:17Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with &amp;quot;:&amp;quot; in their name won&#039;t sync because they can&#039;t be created on an Android fs&lt;br /&gt;
* we can&#039;t use modtime as a criteria for detecting file changes so filesize is the main criteria. We can&#039;t use it because Android does not support this somehow. I&#039;m a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.&lt;br /&gt;
* access to &amp;lt;code&amp;gt;/sdcard&amp;lt;/code&amp;gt; can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again&lt;br /&gt;
* when the script is launched from the home screen it&#039;s nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in &amp;lt;code&amp;gt;.termux/termux.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
 hide-soft-keyboard-on-startup = true&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=594</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=594"/>
		<updated>2024-03-18T23:04:58Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with &amp;quot;:&amp;quot; in their name won&#039;t sync because they can&#039;t be created on an Android fs&lt;br /&gt;
* we can&#039;t use modtime as a criteria for detecting file changes so filesize is the main criteria. We can&#039;t use it because Android does not support this somehow. I&#039;m a man of simple taste, I just need to sync 10GB of memes. Bitrot and tempering can only add value to such endeavor. Check Rclone bisync doc for more options if you find this proposal outrageous.&lt;br /&gt;
* access to &amp;lt;code&amp;gt;/sdcard&amp;lt;code&amp;gt; can stop working sometimes, because Android. Just revoke Termux storage permission and enable them again&lt;br /&gt;
* when the script is launched from the home screen it&#039;s nice to be able to use the whole height of the Android device to scroll back through all these error messages, but by default Termux puts a software keyboard in your face, you can politely decline by adding the following in &amp;lt;code&amp;gt;.termux/termux.properties&amp;lt;/code&amp;gt;&lt;br /&gt;
 hide-soft-keyboard-on-startup = true&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=593</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=593"/>
		<updated>2024-03-18T22:36:49Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* Widget */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with :&lt;br /&gt;
* modtime maybe filesize is the best way&lt;br /&gt;
* access to sdcard&lt;br /&gt;
* remove keyboard&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=592</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=592"/>
		<updated>2024-03-18T22:36:34Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* The script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save it with the very original name &amp;lt;code&amp;gt;sync.sh&amp;lt;/code&amp;gt; and you&#039;re good to go.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;BUT WAIT THERE&#039;S MORE&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Widget ===&lt;br /&gt;
The script is cool but you know what&#039;s more cool? To be able to start it directly from the home launcher thing.&lt;br /&gt;
* Install Termux-widget from F-Droid, an add-on app which adds shortcuts to commands on the home screen.&lt;br /&gt;
* From Termux, move the script to a new special folder&lt;br /&gt;
 mkdir .shortcuts&lt;br /&gt;
 mv sync.sh .shortcuts&lt;br /&gt;
* Go to your home screen and long press to add a Widget, scroll through hundreds of crap widgets, and eventually select the Termux widget.&lt;br /&gt;
* once dropped, sync.sh should automagically be present in the widget menu, or you can also use the single icon widget if you prefer that&lt;br /&gt;
* now you can call the script directly from the home screen.&lt;br /&gt;
* The future is now.&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with :&lt;br /&gt;
* modtime maybe filesize is the best way&lt;br /&gt;
* access to sdcard&lt;br /&gt;
* remove keyboard&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=591</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=591"/>
		<updated>2024-03-18T22:25:55Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* shhhhhhh */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
  do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with :&lt;br /&gt;
* modtime maybe filesize is the best way&lt;br /&gt;
* access to sdcard&lt;br /&gt;
* remove keyboard&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
	<entry>
		<id>https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=590</id>
		<title>Android WebDAV Bi-directional sync with Termux and Rclone</title>
		<link rel="alternate" type="text/html" href="https://things.bleu255.com/runyourown/index.php?title=Android_WebDAV_Bi-directional_sync_with_Termux_and_Rclone&amp;diff=590"/>
		<updated>2024-03-18T22:25:08Z</updated>

		<summary type="html">&lt;p&gt;320x200: /* shhhhhhh */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The purpose of this fantastic documentation is to explain how to setup a very lightweight on-demand manual bi-directional sync between your Android device and a WebDAV share hosted somewhere. It&#039;s fast, and you trade appsolutionism for a cool shell script that you can execute from the comfort of your very own home launcher. This is all possible because of Termux, a terminal emulator application for Android that comes with its apt based package manager, and Rclone, a command-line program to manage files on way too many different cloud storage systems. Seriously it&#039;s ridiculous.&lt;br /&gt;
&lt;br /&gt;
=== Warnings ===&lt;br /&gt;
&lt;br /&gt;
* This documentation makes some assumptions regarding WebDAV and its configuration [[Simple_LAN_filesharing_with_WebDAV | that are described there]].&lt;br /&gt;
* Bi-Directional sync in Rclone is considered experimental at time of writing. See https://rclone.org/bisync/ for more info.&lt;br /&gt;
* This is not a Termux or Rclone tutorial, RTFM or GTFO :) &lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
* Install Termux with F-Droid&lt;br /&gt;
* Make your life easier and access Termux via ssh, read this https://wiki.termux.com/wiki/Remote_Access#Using_the_SSH_server&lt;br /&gt;
* From Termux&lt;br /&gt;
 pkg upgrade&lt;br /&gt;
 pkg install rclone&lt;br /&gt;
* feel free to also install quality of life extras like &amp;lt;code&amp;gt;tmux&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;neovim&amp;lt;/code&amp;gt;, etc&lt;br /&gt;
* configure rclone to work with your WebDAV share, create &amp;lt;code&amp;gt;~/.config/rclone/rclone.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
 [library]&lt;br /&gt;
 type = webdav&lt;br /&gt;
 url = http://192.168.100.100/&lt;br /&gt;
 vendor = other&lt;br /&gt;
 user = turtleprincess&lt;br /&gt;
 pass = SEE_BELOW&lt;br /&gt;
* generate the password with this:&lt;br /&gt;
 echo &amp;quot;heygirl&amp;quot; | rclone obscure -&lt;br /&gt;
* test if it works with&lt;br /&gt;
 rclone lsd library:some/folder&lt;br /&gt;
&lt;br /&gt;
=== Preparing the local and remote folders ===&lt;br /&gt;
Here we will take as example that you want to maintain in sync two folders, the default &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder on your Android device and a remote WebDAV folder of the same name, that can be anywhere in your remote share, for instance &amp;lt;code&amp;gt;library:path/to/Pictures&amp;lt;/code&amp;gt;. &#039;&#039;&#039;Make sure to make a backup of your Android &amp;lt;code&amp;gt;Pictures&amp;lt;/code&amp;gt; folder in case &amp;lt;code&amp;gt;${SOMETHING_B4D}&amp;lt;/code&amp;gt; happens. If you fuck it up, it&#039;s on you. Also follow these three steps below otherwise you will make things worse anyway.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* First we need to test what happens if we ask to populate everything on both sides (content on both local and remote folder will form a superset, so everything will be on both sides) &lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync --dry-run&lt;br /&gt;
* If this looks it&#039;s working fine, then times to stop pretending (drop &amp;lt;code&amp;gt;--dry-run&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case --resync&lt;br /&gt;
* After that, no need to maintain dumb superset sync (drop &amp;lt;code&amp;gt;--resync&amp;lt;/code&amp;gt;)&lt;br /&gt;
 rclone bisync /sdcard/Pictures library:path/to/Pictures --create-empty-src-dirs --compare size --slow-hash-sync-only --resilient -MvP --drive-skip-gdocs --fix-case&lt;br /&gt;
&lt;br /&gt;
If all went well, then you can use the last oneliner whenever you change something on your Android device or on the remote share, and the changes will be propagated to the other. But starting Termux everytime to type this command can be a PITA, except when you&#039;re in public transport and you want to cosplay like you&#039;re breaking into a gibson. So let&#039;s use a script.&lt;br /&gt;
&lt;br /&gt;
== The script ==&lt;br /&gt;
=== shhhhhhh ===&lt;br /&gt;
The following script can sync several folders at the root of the Android user storage, each of them will be treated separately, just make sure that:&lt;br /&gt;
* they also exist on the remote WebDAV share&lt;br /&gt;
* for each of these folders you have done the little 3-steps dance described above&lt;br /&gt;
&lt;br /&gt;
The script has a Wake-on-LAN section, feel free to get rid of it, I sync only on LAN because WAN is overrated and it&#039;s cold outside anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/data/data/com.termux/files/usr/bin/sh&lt;br /&gt;
&lt;br /&gt;
set -e # exit on error&lt;br /&gt;
&lt;br /&gt;
DAVIP=&amp;quot;192.168.100.100&amp;quot;&lt;br /&gt;
DAVMAC=&amp;quot;c0:de:d3:4d:c0:de&amp;quot;&lt;br /&gt;
DAVFOLDER=&amp;quot;library:path/to&amp;quot;&lt;br /&gt;
ANDFOLDERS=&amp;quot;DCIM Pictures Download Documents&amp;quot;&lt;br /&gt;
RETRY=0&lt;br /&gt;
&lt;br /&gt;
kthxbye ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;Press a key to exit...&amp;quot;&lt;br /&gt;
  read REPLY &lt;br /&gt;
  exit 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
syncit ()&lt;br /&gt;
{&lt;br /&gt;
  echo &amp;quot;library is open!\n&amp;quot;&lt;br /&gt;
  # ANSI art greetings (optional but you know you want it)&lt;br /&gt;
  #/data/data/com.termux/files/usr/bin/printf &amp;quot;$(cat ~/assets/tp.ans)&amp;quot;&lt;br /&gt;
  #echo&lt;br /&gt;
  #sleep 3s&lt;br /&gt;
  for ANDFOLDER in ${ANDFOLDERS}&lt;br /&gt;
    do&lt;br /&gt;
    echo &amp;quot;syncing ***${ANDFOLDER}***\n&amp;quot;&lt;br /&gt;
    rclone bisync /sdcard/${ANDFOLDER} ${DAVFOLDER}/${ANDFOLDER} \&lt;br /&gt;
     --create-empty-src-dirs --compare size --slow-hash-sync-only \&lt;br /&gt;
     --resilient -MvP --fix-case&lt;br /&gt;
  done&lt;br /&gt;
  kthxbye&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
gotolibrary ()&lt;br /&gt;
{&lt;br /&gt;
  if nc -w 2 -z ${DAVIP} 80 2&amp;gt;/dev/null&lt;br /&gt;
  then&lt;br /&gt;
    syncit&lt;br /&gt;
  else&lt;br /&gt;
    echo &amp;quot;library is silent, trying to wakeup turtle princess&amp;quot;&lt;br /&gt;
    if [ &amp;quot;${RETRY}&amp;quot; -eq 0 ] ; then wol ${DAVMAC} ; fi&lt;br /&gt;
    while [ &amp;quot;${RETRY}&amp;quot; -lt 20 ]&lt;br /&gt;
    do&lt;br /&gt;
      sleep 1s&lt;br /&gt;
      RETRY=$((RETRY+1))&lt;br /&gt;
      gotolibrary&lt;br /&gt;
    done&lt;br /&gt;
    echo &amp;quot;OK I give up, library is closed :(&amp;quot;&lt;br /&gt;
    kthxbye&lt;br /&gt;
  fi&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
gotolibrary&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
* files with :&lt;br /&gt;
* modtime maybe filesize is the best way&lt;br /&gt;
* access to sdcard&lt;br /&gt;
* remove keyboard&lt;/div&gt;</summary>
		<author><name>320x200</name></author>
	</entry>
</feed>