Blog on Crony Akatsuki's Website https://cronyakatsuki.xyz/blog/ Recent content in Blog on Crony Akatsuki's Website Hugo -- gohugo.io en-us Thu, 04 Apr 2024 20:44:10 +0200 Securing Ssh https://cronyakatsuki.xyz/blog/securing-ssh/ 04-04-2024 https://cronyakatsuki.xyz/blog/securing-ssh/ <p>As someone who has a couple of servers out in the open web, one of the main things I had to learn was how to secure it so people can&rsquo;t touch them. One of the main ways to do that is by hardening ssh.</p> <p>Here I will name a couple of settings and best practices to make sure your ssh is as secure as possible.</p> <hr> <h2 id="use-key-pairs">Use key pairs</h2> <p>One of the main practice to secure ssh is by using public/private ssh key pair and making ssh only allow connection with them, disabling password login.</p> <p>First you need to generate a key pair by running the commmand <code>ssh-keygen</code>.</p> <p>After generating the key and the command <code>ssh-copy-id ~/.ssh/key_name user@host</code> to copy the key to the server.</p> <p>Connection to the server now it will ask you for the ssh key password if you set one, if you didn&rsquo;t then it will just directly connect it.</p> <p>While you are connected to the server now, I would recommend you to change next settings to the values I recommend to make sure you can only connect to the server with ssh key pairs already on the server. Make sure to uncommmend the values in your config, and change like I did in my examples.</p> <blockquote> <p>/etc/ssh/sshd_config</p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">PubkeyAuthentication yes PasswordAuthentication no PermitEmptyPasswords no </code></pre><p>Restart your sshd service, with <code>systemctl restart sshd.service</code>.</p> <h2 id="disable-root-user-logins">Disable root user logins</h2> <p>Next most common way to secure ssh is by not using a root account to connect, so even if somebody manages to connect they don&rsquo;t get root user access.</p> <p>After creating a new user ( make sure to add it to sudo/wheel group also ), make sure to copy the file located in <code>/root/.ssh/authorized_keys</code> to your new users directory in path <code>/home/user/.ssh/authorized_keys</code></p> <p>I would reccommend at this point to try and connecting to the different user on the server to make sure the ssh keys were copied correctly. ( example <code>ssh new-user@host</code> )</p> <p>After that, disable root user login and only allow connecting to ssh with the new user.</p> <blockquote> <p>/etc/ssh/sshd_config</p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">PermitRootLogin no AllowUsers new-user </code></pre><p>Restart your sshd service.</p> <h2 id="only-allow-connection-from-specific-ip">Only allow connection from specific ip</h2> <p>Next best way to secure ssh is to only allow connection from specific ip, preferably vpn.</p> <p>Main way I do it is using wireguard. I set it up using the landchad <a href="https://landchad.net/wireguard">guide</a>.</p> <p>Then in your sshd config you can make it so that ssh will only accept connection to the user with only the current using syntax.</p> <pre tabindex="0"><code class="language-conf" data-lang="conf">AllowUsers new-user@172.16.0.2 </code></pre><p>You can use the ip for the connection you use to setup the peer in the wireguard setup guide, which in landchad&rsquo;s guide is <code>172.16.0.2</code>. Or from another server by using the ip of the server you connect with wireguard to.</p> <p>Make sure to restart sshd and test out in another terminal window whether you can only connect with the wireguard connection to the server ( Don&rsquo;t close or exit the current ssh connection before making sure it all work&rsquo;s ).</p> <h2 id="general-settings">General settings</h2> <p>There are some more settings that can be changed and I will name them now.</p> <pre tabindex="0"><code class="language-conf" data-lang="conf"># Port change to allow connection from only that port, to connect use &#34;ssh new-user@host -p port&#34; Port 4893 # Allow connection only from ipv4 AddressFamily inet # Limit to only 3 connection tries MaxAuthTries 3 # Disable pam UsePAM no # Disable tcp and x11 forwarding AllowTcpForwarding no X11Forwarding no </code></pre><p>If you by chance need tcp or x11 forwarding, enable it only for your user using this syntax:</p> <pre tabindex="0"><code class="language-conf" data-lang="conf">Match User new-user AllowTcpForwarding yes X11Forwarding yes </code></pre><hr> <p>With this I have covered the most basic, but at the same best practices to secure your server ssh to not get uninvited people connecting to your servers.</p> Setup Traefik https://cronyakatsuki.xyz/blog/setup-traefik/ 19-01-2024 https://cronyakatsuki.xyz/blog/setup-traefik/ <p>Do you use docker? Do you use nginx or apachi to proxy the container? Fear not you won&rsquo;t be needing them anymore once you are done with this tutorial.</p> <p>Traefik is a simple docker centric proxy manager that is amazing and allows you to easilly proxy you docker containers with just a couple of labels.</p> <!-- raw HTML omitted --> <h1 id="setting-up-traefik">Setting up Traefik</h1> <p>In this part we will setup traefik, with the dashboard enabled and secured with https and a password.</p> <p>Create a directory where you will keep traefik configuration files and the docker compose. Inside it we will save all the configuration files.</p> <h2 id="docker-composeyml">docker-compose.yml</h2> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span><span style="color:#ca9ee6">version</span>: <span style="color:#a6d189">&#39;3&#39;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">services</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">traefik</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">image</span>: traefik:v2.5 </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">container_name</span>: traefik </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">ports</span>: </span></span><span style="display:flex;"><span> - <span style="color:#ef9f76">80</span>:<span style="color:#ef9f76">80</span> </span></span><span style="display:flex;"><span> - <span style="color:#ef9f76">443</span>:<span style="color:#ef9f76">443</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">volumes</span>: </span></span><span style="display:flex;"><span> - ./traefik.toml:/traefik.toml </span></span><span style="display:flex;"><span> - ./traefik_dynamic.toml:/traefik_dynamic.toml </span></span><span style="display:flex;"><span> - /var/run/docker.sock:/var/run/docker.sock:ro </span></span><span style="display:flex;"><span> - ./acme.json:/acme.json </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> - web </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.enable=false </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">restart</span>: unless-stopped </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">web</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">external</span>: <span style="color:#ef9f76">true</span> </span></span></code></pre></div><p>What we are doing here is binding the needed configuration files, the docker socket so traefik can listen to it and automatically proxy the services, and the acme.json which will keep our ssl certificates.</p> <p>We are also forcing it to use the latest available stable image to make sure there are no bugs, and disabling proxying the traefik image itself io the lables to make sure it isn&rsquo;t exposed by any means.</p> <p>We are also making it so it can restart itself unless we specifically stop it, and binding it to port 80 and 443 because those are the default http and https ports that every browser uses when connecting.</p> <h2 id="traefiktoml">traefik.toml</h2> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[entryPoints] </span></span><span style="display:flex;"><span> [entryPoints.web] </span></span><span style="display:flex;"><span> address = <span style="color:#a6d189">&#34;:80&#34;</span> </span></span><span style="display:flex;"><span> [entryPoints.web.http.redirections.entryPoint] </span></span><span style="display:flex;"><span> to = <span style="color:#a6d189">&#34;websecure&#34;</span> </span></span><span style="display:flex;"><span> scheme = <span style="color:#a6d189">&#34;https&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> [entryPoints.websecure] </span></span><span style="display:flex;"><span> address = <span style="color:#a6d189">&#34;:443&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>[api] </span></span><span style="display:flex;"><span> dashboard = <span style="color:#ef9f76">true</span> </span></span><span style="display:flex;"><span> insecure = <span style="color:#ef9f76">false</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>[certificatesResolvers.lets-encrypt.acme] </span></span><span style="display:flex;"><span> email = <span style="color:#a6d189">&#34;name@domain.tld&#34;</span> </span></span><span style="display:flex;"><span> storage = <span style="color:#a6d189">&#34;acme.json&#34;</span> </span></span><span style="display:flex;"><span> [certificatesResolvers.lets-encrypt.acme.tlsChallenge] </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>[providers.docker] </span></span><span style="display:flex;"><span> watch = <span style="color:#ef9f76">true</span> </span></span><span style="display:flex;"><span> network = <span style="color:#a6d189">&#34;web&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>[providers.file] </span></span><span style="display:flex;"><span> filename = <span style="color:#a6d189">&#34;traefik_dynamic.toml&#34;</span> </span></span><span style="display:flex;"><span> watch = <span style="color:#ef9f76">true</span> </span></span></code></pre></div><p>In the entryPoints we are defining the http and https ports and forcing http to redirect to https.</p> <p>In the api section we are enabling the dashboard, but disallowing insecure access to it.</p> <p>In the rest of the config we are defining the mail and storage for tls certificates, and enabled docker provider binded to a web network, and enabled the file provider for the dashboard setup.</p> <h2 id="traefik_dynamictoml">traefik_dynamic.toml</h2> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[http.middlewares.simpleAuth.basicAuth] </span></span><span style="display:flex;"><span> users = [ </span></span><span style="display:flex;"><span> <span style="color:#a6d189">&#34;somebody:$apr1$whatever&#34;</span> </span></span><span style="display:flex;"><span> ] </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>[http.routers.api] </span></span><span style="display:flex;"><span> rule = <span style="color:#a6d189">&#34;Host(`monitor.domain.tld`)&#34;</span> </span></span><span style="display:flex;"><span> entrypoints = [<span style="color:#a6d189">&#34;websecure&#34;</span>] </span></span><span style="display:flex;"><span> middlewares = [<span style="color:#a6d189">&#34;simpleAuth&#34;</span>] </span></span><span style="display:flex;"><span> service = <span style="color:#a6d189">&#34;api@internal&#34;</span> </span></span><span style="display:flex;"><span> [http.routers.api.tls] </span></span><span style="display:flex;"><span> certResolver = <span style="color:#a6d189">&#34;lets-encrypt&#34;</span> </span></span></code></pre></div><p>Here we are defining the basic auth credentials and routing the monitor domain to the dashboard with basic auth credentials and https.</p> <p>Make sure to subsitute the string in qutes for users with what you get generated with httpasswd command: <code>htpasswd -n somebody</code>.</p> <h2 id="acmetoml">acme.toml</h2> <p>To create <code>acme.toml</code> run this command <code>touch acme.toml &amp;&amp; chmod 600 acme.toml</code> and we are done.</p> <h2 id="docker-web-network">docker web network</h2> <p>You might have seen the networks part in the docker compose, we need to create it to make other docker containers in different docker compose files be accessible to traefik so it can proxy to them.</p> <p>To create it we just need to run <code>docker network create web</code> and we are done.</p> <hr> <p>After all this is done, we can just run <code>docker compose up -d</code> and if everyting was setup correctly, running <code>docker compose logs -f</code> shouldn&rsquo;t show any errors.</p> <h1 id="using-trafik-to-proxy-to-docker-containers">Using trafik to proxy to docker containers</h1> <p>Now I&rsquo;m going to explain to you how to use traefik to proxy to docker containers by using labels. For that I will be using ntfy docker image as an example.</p> <blockquote> <p>docker-compose.yml</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yml" data-lang="yml"><span style="display:flex;"><span><span style="color:#ca9ee6">version</span>: <span style="color:#a6d189">&#34;2.3&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">services</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">ntfy</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">image</span>: binwiederhier/ntfy </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">container_name</span>: ntfy </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">command</span>: </span></span><span style="display:flex;"><span> - serve </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">volumes</span>: </span></span><span style="display:flex;"><span> - ./cache:/var/cache/ntfy </span></span><span style="display:flex;"><span> - ./ntfy:/etc/ntfy </span></span><span style="display:flex;"><span> - ./users:/var/lib/ntfy </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">healthcheck</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">test</span>: [<span style="color:#a6d189">&#34;CMD-SHELL&#34;</span>, <span style="color:#a6d189">&#34;wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo &#39;\&#34;healthy\&#34;\\s*:\\s*true&#39; || exit 1&#34;</span>] </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">interval</span>: 60s </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">timeout</span>: 10s </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">retries</span>: <span style="color:#ef9f76">3</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">start_period</span>: 40s </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">restart</span>: unless-stopped </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> - web </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.http.routers.ntfy.rule=Host(`ntfy.domain.tld`) </span></span><span style="display:flex;"><span> - traefik.http.routers.ntfy.tls=true </span></span><span style="display:flex;"><span> - traefik.http.routers.ntfy.entrypoints=websecure </span></span><span style="display:flex;"><span> - traefik.http.routers.ntfy.tls.certresolver=lets-encrypt </span></span><span style="display:flex;"><span> - traefik.port=80 </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">web</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">external</span>: <span style="color:#ef9f76">true</span> </span></span></code></pre></div><p>The important part&rsquo;s of this docker compose are the following:</p> <ul> <li> <h2 id="no-exposing-ports">No exposing ports</h2> </li> </ul> <p>As you can see, with traefik you don&rsquo;t need to expose port&rsquo;s from the container making it a lot more secure as it can directly proxy to them from itself using the web network.</p> <ul> <li> <h2 id="labels">labels</h2> </li> </ul> <p>In labels we are defining the host domain we wan&rsquo;t to proxy to our container, we are also enabled tls and with entrypoints making the container only acessible from https, making it impossible to be accessible with http no matter what.</p> <p>We are also defining the certresolver to be lets-encrypt and setting the port from the container that traefik needs to proxy to 80, this port can be different depending on what you want to proxy.</p> <ul> <li> <h2 id="networks">networks</h2> </li> </ul> <p>We are also defining the web external network that is ussed so traefik can access to the container and proxy to it.</p> <hr> <p>After you have accustomed the config to what you need, you can just <code>docker compose up -d</code>, go to your traefik monitor and after some time you will see ntfy addedd to reverse proxying with tls certficate and only accessible from https.</p> <h1 id="disabling-traefik">Disabling traefik</h1> <p>Next I will be talkling about how to disable traefik for containers because you don&rsquo;t want it to work for containers you dont want accessible over the network.</p> <h2 id="disabling-for-one-service-docker-compose">Disabling for one service docker-compose</h2> <p>As the main example, I have a watchtower instance that I dont wan&rsquo;t proxied to the outside world. To do that we just add <code>traefik.enable=false</code> to the labels and trafik will stop being naughty.</p> <blockquote> <p>example</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ef9f76">...</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.enable=false </span></span><span style="display:flex;"><span><span style="color:#ef9f76">...</span> </span></span></code></pre></div><p>Take note that for this kind of docker-compose files, networks part IS NOT NEEDED, just create the docker compose file as you would usually without having the networks part.</p> <h2 id="disabling-for-more-complex-docker-compose">Disabling for more complex docker-compose</h2> <p>Now here comes the more tricky part, disabling it for only specific docker containers, and making it so traefik cant access them from its network. To accomplish that we will use the <code>traefik.enable=false</code> label once again, and make use of multiple networks to make sure traefik can only access the web interfaces and keep other containers secure like databases and only accessible to the web interfaces.</p> <blockquote> <p>example docker-compose.yml</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#ca9ee6">version</span>: <span style="color:#a6d189">&#34;3&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">web</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">external</span>: <span style="color:#ef9f76">true</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">internal</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">external</span>: <span style="color:#ef9f76">false</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">services</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">blog</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">image</span>: wordpress:4.9.8-apache </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">environment</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">WORDPRESS_DB_PASSWORD</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.http.routers.blog.rule=Host(`blog.domain.tld`) </span></span><span style="display:flex;"><span> - traefik.http.routers.blog.tls=true </span></span><span style="display:flex;"><span> - traefik.http.routers.blog.tls.certresolver=lets-encrypt </span></span><span style="display:flex;"><span> - traefik.port=80 </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> - internal </span></span><span style="display:flex;"><span> - web </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">depends_on</span>: </span></span><span style="display:flex;"><span> - mysql </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">mysql</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">image</span>: mysql:5.7 </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">environment</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">MYSQL_ROOT_PASSWORD</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> - internal </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.enable=false </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">adminer</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">image</span>: adminer:4.6.3-standalone </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">labels</span>: </span></span><span style="display:flex;"><span> - traefik.http.routers.adminer.rule=Host(`db-admin.domain.tld`) </span></span><span style="display:flex;"><span> - traefik.http.routers.adminer.tls=true </span></span><span style="display:flex;"><span> - traefik.http.routers.adminer.tls.certresolver=lets-encrypt </span></span><span style="display:flex;"><span> - traefik.port=8080 </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">networks</span>: </span></span><span style="display:flex;"><span> - internal </span></span><span style="display:flex;"><span> - web </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">depends_on</span>: </span></span><span style="display:flex;"><span> - mysql </span></span></code></pre></div><p>Here we can see what I was talking about in action, take note I took this docker compose file from this digital ocean <a href="https://www.digitalocean.com/community/tutorials/how-to-use-traefik-v2-as-a-reverse-proxy-for-docker-containers-on-ubuntu-20-04#step-3-registering-containers-with-traefik">blog post</a> that explains it a lot better I could which you can use as a reference if you didnt understand something about what I was talking about.</p> <h1 id="conclusing">Conclusing</h1> <p>I hope that you were able to setup traefik, or if not and were just reading to see what its all about I hope you had a good read and might have decided to try out traefik in the future.</p> Using Mblaze https://cronyakatsuki.xyz/blog/using-mblaze/ 07-01-2024 https://cronyakatsuki.xyz/blog/using-mblaze/ <p>So you followed my last tutorial on setting up mblaze and friend&rsquo;s for you mail management, but now you are left just looking at it not understanding how to use the power you have been given now. So now I&rsquo;m going to teach you some basic usage that you can have with it.</p> <h1 id="helper-functions">Helper function&rsquo;s</h1> <p>I guess you haven&rsquo;t read my other blog on setting up mblaze and friend&rsquo;s if you need me to type them out here again, so go read it now! Here is the <a href="https://cronyakatsuki.xyz/blog/virgin-mutt-user-meet-mblaze/">link</a>.</p> <h1 id="getting-mail-and-reading-it">Getting mail and reading it</h1> <p>Now after you have actually read my last blog and got the two function&rsquo;s and the script installed and made them usefull, we can start getting and reading our mail.</p> <p>First you will choose what mail you wanna manage, or how I call it profile with my script.</p> <p>After choosing it you will now have to choose if you wan&rsquo;t to see all mail available on the server, or you will be just reading the new mail and based on that run either <code>mall</code> or <code>mnew</code>.</p> <p>Now we have a couple way&rsquo;s of listing and reading mail.</p> <p>We can use the command <code>mscan</code> that will show you simple one line summaries of your mail. The mail with <code>.</code> mean their status is undread.</p> <p>To read a single specific message we can use <code>mshow</code>. By default it will use the mail that when using <code>mscan</code> show&rsquo;s &gt; as <strong>currently choosen</strong> mail. To read another mail you can choose the number of the mail from <code>mscan</code> and use mshow like this <code>mshow N</code> ( N being the number of the mail you wan&rsquo;t to read ).</p> <p>Now onto my favourite way of reading mail with mblaze, it&rsquo;s <code>mless</code>. You just run it and it will run a less instance showing all your mail, and have the ability to change between them with keybindings <code>:p</code> and <code>:n</code> with p going to preview and n going to next message.</p> <h1 id="settings-read-status">Settings read status</h1> <p>To flag mail as read we can use the mflag utiity. We do it by choosing what mail we wanna mark as read and running the command <code>mflag -S N</code>, but after that we need to fix our list because the filename changed because of the fact that we changed the flag to read. To fix that we will run <code>mseq -f : | mseq -S</code>.</p> <p>We can easily alias this sequence of command&rsquo;s into a function to streamline this.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#ca9ee6">function</span> mread<span style="color:#99d1db;font-weight:bold">()</span> <span style="color:#99d1db;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> mflag -S <span style="color:#f2d5cf">$1</span> </span></span><span style="display:flex;"><span> mseq -f : | mseq -S </span></span><span style="display:flex;"><span><span style="color:#99d1db;font-weight:bold">}</span> </span></span></code></pre></div><p>You can place this function anywhere in your shell configuration.</p> <h1 id="sending-mail">Sending mail</h1> <p>To write mail with mblaze we use command called <code>mcom</code>. After running it, it will a file in your editor of choice that looks like this:</p> <pre tabindex="0"><code class="language-devbox" data-lang="devbox">To: Cc: Bcc: Subject: From: John Doe &lt;john@doe.com&gt; Message-Id: &lt;random-id&gt; User-Agent: mblaze/... </code></pre><p>In the <code>To:</code> file you write the name of mail you wan&rsquo;t to send to for example <code>Shit Shittington &lt;shit@shittington.com&gt;</code> and subject to name of the subject like regular mail.</p> <p>After that you type the message in the last empty line at the bottom, of course you can make it as long as you wan&rsquo;t to.</p> <p>If you save the message as draft just run <code>mcom -r</code>. To reply to a message use <code>mrep N</code> to reply to a specific message.</p> <h1 id="extending-mless-functionalitty">Extending mless functionalitty</h1> <p>We can extend the functionality of mless a bit by creating a file with custom keybindings that will go ahead and a few more function&rsquo;s to mless.</p> <p>Save this file to <code>~/.mblaze/mlesskey</code></p> <pre tabindex="0"><code class="language-lesskey" data-lang="lesskey">Q quit \1 :cq quit \1 [ prev-file ] next-file { noaction E1\n } quit $ $ quit $ S noaction E//scan\n ` noaction E\#\n H quit H N quit N R quit R K quit k d quit d \^ quit \^ </code></pre><p>This will add keybindings like <code>]</code> and <code>[</code> for previous and next mail and <code>d</code> for setting read status on mail. Rest you can checkout yourself by looking at this part of mless script on github, <a href="https://github.com/leahneukirchen/mblaze/blob/master/mless#L92">link</a>.</p> <h1 id="conclusion">Conclusion</h1> <p>I guess this is it now, hope this help&rsquo;s you on making your own mail be even more amazing.</p> Hardening Level Pro: Notify on SSH Login https://cronyakatsuki.xyz/blog/hardening-level-pro-notify-on-ssh-login/ 10-11-2023 https://cronyakatsuki.xyz/blog/hardening-level-pro-notify-on-ssh-login/ <p>You ever anxious about somebody possibly gaining access to your machine? Fret not, you can just make it so that on any kind of login to your system directly you can get a notification on your phone.</p> <p>For this you will need a way to receive the messaggess. I personally use a selfhosted <a href="https://ntfy.sh/">ntfy.sh</a> server.</p> <p>The most important way of managing your linux vps or in general any machine for most of us is ssh. So why not just get a notification whenever somebody logins!? Even you!</p> <p>To achieve this you will need to make a shell script and use a pam module, yes you will need to enable UsePAM in your sshd config, but don&rsquo;t worry it&rsquo;s secure.</p> <blockquote> <p>/usr/bin/ntfy-ssh-login.sh</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic">#!/bin/bash </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span><span style="color:#ca9ee6">if</span> <span style="color:#99d1db;font-weight:bold">[</span> <span style="color:#a6d189">&#34;</span><span style="color:#a6d189">${</span><span style="color:#f2d5cf">PAM_TYPE</span><span style="color:#a6d189">}</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">=</span> <span style="color:#a6d189">&#34;open_session&#34;</span> <span style="color:#99d1db;font-weight:bold">]</span>; <span style="color:#ca9ee6">then</span> </span></span><span style="display:flex;"><span> curl <span style="color:#8caaee">\ </span></span></span><span style="display:flex;"><span><span style="color:#8caaee"></span> -H prio:high <span style="color:#8caaee">\ </span></span></span><span style="display:flex;"><span><span style="color:#8caaee"></span> -H tags:warning <span style="color:#8caaee">\ </span></span></span><span style="display:flex;"><span><span style="color:#8caaee"></span> -d <span style="color:#a6d189">&#34;SSH login: </span><span style="color:#a6d189">${</span><span style="color:#f2d5cf">PAM_USER</span><span style="color:#a6d189">}</span><span style="color:#a6d189"> from </span><span style="color:#a6d189">${</span><span style="color:#f2d5cf">PAM_RHOST</span><span style="color:#a6d189">}</span><span style="color:#a6d189">&#34;</span> <span style="color:#8caaee">\ </span></span></span><span style="display:flex;"><span><span style="color:#8caaee"></span> ntfy.sh/<span style="color:#99d1db;font-weight:bold">{</span>YourTopic<span style="color:#99d1db;font-weight:bold">}</span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">fi</span> </span></span></code></pre></div><blockquote> <p>/etc/pam.d/sshd</p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf"># at the end of the file session optional pam_exec.so /usr/bin/ntfy-ssh-login.sh </code></pre><p>Also make sure that pam is realoaded using this command <code>pam-auth-update --force --package</code>.</p> <p>You can modify the script to do email or anything else, but I prefer ntfy since the notification are instant.</p> <p>Hope this was of help and let&rsquo;s see you in another post.</p> Virgin (Neo)Mutt User Meet Mblaze https://cronyakatsuki.xyz/blog/virgin-mutt-user-meet-mblaze/ 24-10-2023 https://cronyakatsuki.xyz/blog/virgin-mutt-user-meet-mblaze/ <p>We have all heard of (Neo)Mutt when it comes to managing e-mail in the terminal right? What would you do if I told you there is an even better and more UNIX way to manage mail on the terminal? Well there is and it&rsquo;s called <a href="https://github.com/leahneukirchen/mblaze">mblaze</a>.</p> <p>In this post I will explain to you how to setup mblaze for managing your email, but for that we will 2 more additional software to manage our mail with mblaze. <a href="https://www.opensmtpd.org/">OpenSMTPD</a> the openbsd fast mail server for getting local mail from services like crontab and sending mail with, and <a href="https://isync.sourceforge.io/">isync</a> for downloading our mail from our remote server&rsquo;s either selfhosted or gmail.</p> <h1 id="1-opensmtpd">1. OpenSMTPD</h1> <p>First we will setup OpenSMTP for local mail, and we will also relay&rsquo;s that allow us to send e-mail from our selfhosted or gmail mail server&rsquo;s for example. Make sure to install opensmtpd from your package maanager.</p> <blockquote> <p>Edit <code>/etc/smtpd/smtpd.conf</code></p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">table aliases file:/etc/mail/aliases table credentials file:/etc/mail/credentials listen on 127.0.0.1 action &#34;local_mail&#34; maildir &#34;/home/%{user.username}/.local/share/Maildir/local&#34; alias &lt;aliases&gt; action outbound_selfhost relay host smtp+tls://selfhost@subdomain.domain.com:587 auth &lt;credentials&gt; action outbound_gmail relay host smtp+tls://gmail@smtp.gmail.com:587 auth &lt;credentials&gt; match for local action &#34;local_mail&#34; match mail-from &#34;selfhost@domain.com&#34; for any action outbound_selfhost match mail-from &#34;username@gmail.com&#34; for any action outbound_gmail </code></pre><p>Next you will need to update aliases in file /etc/mail/aliases under the comment <code># Well-known aliases -- these should be filled in!</code> to your main user account on your system.</p> <p>Now we will also setup the passwords in the <code>/etc/mail/credentials</code>, Note for gmail you will need to setup app password for it to be usable with this method and enable smtp in gmail.</p> <pre tabindex="0"><code class="language-conf" data-lang="conf">selfhost selfhost:selfhost_password gmail gmail:gmail_password </code></pre><p>Also make sure to run <code>sudo chmod 600 /etc/mail/credentials</code> to make sure the password&rsquo;s aren&rsquo;t readable if you aren&rsquo;t running as sudo.</p> <h1 id="2-isync">2. isync</h1> <p>Now we will setup isync to get our e-mail from our server&rsquo;s. In this example there is both settings for a selfhosted server and a gmail one.</p> <blockquote> <p>Edit <code>$HOME/.mbsyncrc</code></p> </blockquote> <pre tabindex="0"><code class="language-rc" data-lang="rc">IMAPStore selfhost-remote Host subdomain.domain.com Port 993 User selfhost@domain.com PassCmd &#34;Command for password&#34; or Pass password SSLType IMAPS CertificateFile /etc/ssl/certs/ca-certificates.crt MaildirStore selfhost-local Path ~/.local/share/Maildir/selfhost/ Inbox ~/.local/share/Maildir/selfhost/INBOX SubFolders Verbatim Channel selfhost Far :selfhost-remote: Near :selfhost-local: Create Both Expunge Both Patterns * !&#34;[Gmail]/All Mail&#34; !&#34;*fts-flatcurve*&#34; !&#34;*virtual*&#34; SyncState * Create Both IMAPStore gmail-remote Host imap.gmail.com Port 993 User gmail@gmail.com PassCmd &#34;Command for password&#34; or Pass password SSLType IMAPS CertificateFile /etc/ssl/certs/ca-certificates.crt MaildirStore gmail-local Path ~/.local/share/Maildir/gmail/ Inbox ~/.local/share/Maildir/gmail/INBOX SubFolders Verbatim Channel gmail Far :gmail-remote: Near :gmail-local: Create Both Expunge Both Patterns * !&#34;[Gmail]/All Mail&#34; !&#34;*fts-flatcurve*&#34; !&#34;*virtual*&#34; SyncState * Create Both </code></pre><p>Then you can run <code>mbsync -V gmail/selfhost</code> to sync a specific account or you can run <code>mbsync -a</code> to sync all your account&rsquo;s.</p> <h1 id="3-mblaze">3. mblaze</h1> <p>Now we will start working on the most juicy part, setting up mblaze for basic usage. First we will setup a basic mblaze profile for our local account.</p> <blockquote> <p>Edit <code>$HOME/.mblaze/profile</code></p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">Local-Mailbox: user FQDN: &#34;Generate using command mgenmid&#34; Maildir: /home/USER/.local/share/Maildir/local Outbox: /home/USER/.local/share/Maildir/local/Sent/ Drafts: /home/USER/.local/share/Maildir/local/Drafts/ Reply-From: user # You don&#39;t need this, it just makes it easier to see date Scan-Format: %c%u%r %-3n %10d %17f %t %2i%s </code></pre><p>And now we are ready for using mblaze for managing our local mail with mblaze. Now for the rest of this blog I will show how I manage multiple account&rsquo;s using a scipt and a couple function&rsquo;s. I will also link a video that will show you in more detail things for using mblaze for managing your mail which was my inspiration for making this post.</p> <h1 id="4-multiple-profiles-management">4. Multiple profiles management</h1> <p>You can do this in a lot of ways with mblaze since it is very easily scriptable, but I do it with a script that copies over a preconfigure profile from <code>$HOME/.config/mblaze</code></p> <blockquote> <p>example selfhost mblaze config <code>$HOME/.config/mblaze/selfhost</code></p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">Local-Mailbox: User Name &lt;user@domain.com&gt; FQDN: &#34;Generate using command mgenmid&#34; Maildir: /home/USER/.local/share/Maildir/selfhost Outbox: /home/USER/.local/share/Maildir/selfhost/Sent/ Drafts: /home/USER/.local/share/Maildir/selfhost/Drafts/ Reply-From: User Name &lt;user@domain.com&gt; Scan-Format: %c%u%r %-3n %10d %17f %t %2i%s </code></pre><blockquote> <p>example gmail mblaze config <code>$HOME/.config/mblaze/gmail</code></p> </blockquote> <pre tabindex="0"><code class="language-conf" data-lang="conf">Local-Mailbox: user &lt;user@gmail.com&gt; FQDN: &#34;Generate using command mgenmid&#34; Maildir: /home/USER/.local/share/Maildir/gmail Outbox: /home/USER/.local/share/Maildir/gmail/[Gmail]/Sent Mail Drafts: /home/USER/.local/share/Maildir/gmail/[Gmail]/Drafts Reply-From: user &lt;user@gmail.com&gt; Scan-Format: %c%u%r %-3n %10d %17f %t %2i%s </code></pre><p>For the local profile, just copy the config saved to <code>$HOME/.mblaze/profile</code> to <code>$HOME/.config/mblaze/local</code>.</p> <p>Now onto the script and functions I use with my zsh.</p> <blockquote> <p>mprofile</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic">#!/bin/sh </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">profiles</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>find <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$HOME</span><span style="color:#a6d189">&#34;</span>/.config/mblaze -type f -exec basename <span style="color:#a6d189">&#34;{}&#34;</span> <span style="color:#8caaee">\;</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">currentMaildir</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>grep <span style="color:#a6d189">&#34;^Maildir:&#34;</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$HOME</span><span style="color:#a6d189">&#34;</span>/.mblaze/profile | cut -d: -f <span style="color:#ef9f76">2</span> | sed <span style="color:#a6d189">&#39;s/ //g&#39;</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#99d1db;font-weight:bold">[</span> -z <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$1</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">]</span> <span style="color:#99d1db;font-weight:bold">&amp;&amp;</span> basename <span style="color:#a6d189">&#34;</span><span style="color:#ca9ee6">$(</span>grep -w <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$currentMaildir</span><span style="color:#a6d189">&#34;</span> -l -R <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$HOME</span><span style="color:#a6d189">&#34;</span>/.config/mblaze<span style="color:#ca9ee6">)</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">&amp;&amp;</span> <span style="color:#99d1db">exit</span> <span style="color:#ef9f76">0</span> </span></span><span style="display:flex;"><span><span style="color:#99d1db;font-weight:bold">[</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$1</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">=</span> <span style="color:#a6d189">&#34;-l&#34;</span> <span style="color:#99d1db;font-weight:bold">]</span> <span style="color:#99d1db;font-weight:bold">&amp;&amp;</span> <span style="color:#99d1db">printf</span> <span style="color:#a6d189">&#39;%s\n&#39;</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profiles</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">&amp;&amp;</span> <span style="color:#99d1db">exit</span> <span style="color:#ef9f76">0</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">profile</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$1</span><span style="color:#a6d189">&#34;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">if</span> <span style="color:#99d1db">printf</span> <span style="color:#a6d189">&#39;%s\n&#39;</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profiles</span><span style="color:#a6d189">&#34;</span> | grep -qw <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profile</span><span style="color:#a6d189">&#34;</span>; <span style="color:#ca9ee6">then</span> </span></span><span style="display:flex;"><span> cp <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$HOME</span><span style="color:#a6d189">&#34;</span>/.config/mblaze/<span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profile</span><span style="color:#a6d189">&#34;</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$HOME</span><span style="color:#a6d189">&#34;</span>/.mblaze/profile </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">else</span> </span></span><span style="display:flex;"><span> <span style="color:#99d1db">printf</span> <span style="color:#a6d189">&#39;%s\n&#39;</span> <span style="color:#a6d189">&#34;This profile doesn&#39;t exist&#34;</span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">fi</span> </span></span></code></pre></div><p>The script is able to print the current profile when run without argument, listing all available profiles using -l and setting the profile by providing it&rsquo;s name.</p> <blockquote> <p>functions</p> </blockquote> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># mblaze functions</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Get new mail for current profile</span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">function</span> mnew <span style="color:#99d1db;font-weight:bold">()</span> <span style="color:#99d1db;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#f2d5cf">maildir</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>grep <span style="color:#a6d189">&#34;^Maildir:&#34;</span> <span style="color:#f2d5cf">$HOME</span>/.mblaze/profile | cut -d: -f <span style="color:#ef9f76">2</span> | sed <span style="color:#a6d189">&#39;s/ //g&#39;</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> <span style="color:#f2d5cf">profile</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>basename <span style="color:#f2d5cf">$maildir</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">if</span> <span style="color:#99d1db;font-weight:bold">[</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profile</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">=</span> <span style="color:#a6d189">&#34;local&#34;</span> <span style="color:#99d1db;font-weight:bold">]</span>; <span style="color:#ca9ee6">then</span> </span></span><span style="display:flex;"><span> mlist -s <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">&#34;</span>| msort -dr | mseq -S </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">else</span> </span></span><span style="display:flex;"><span> mbsync -V <span style="color:#f2d5cf">$profile</span> </span></span><span style="display:flex;"><span> mlist -s <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">&#34;</span>/INBOX | msort -dr | mseq -S </span></span><span style="display:flex;"><span> minc <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">/INBOX&#34;</span> &gt; /dev/null </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">fi</span> </span></span><span style="display:flex;"><span><span style="color:#99d1db;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Get full mail for current profile including threads</span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">function</span> mall <span style="color:#99d1db;font-weight:bold">()</span> <span style="color:#99d1db;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#f2d5cf">maildir</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>grep <span style="color:#a6d189">&#34;^Maildir:&#34;</span> <span style="color:#f2d5cf">$HOME</span>/.mblaze/profile | cut -d: -f <span style="color:#ef9f76">2</span> | sed <span style="color:#a6d189">&#39;s/ //g&#39;</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> <span style="color:#f2d5cf">sent</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>grep <span style="color:#a6d189">&#34;^Outbox:&#34;</span> <span style="color:#f2d5cf">$HOME</span>/.mblaze/profile | cut -d: -f <span style="color:#ef9f76">2</span> | sed <span style="color:#a6d189">&#39;s/ //g&#39;</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> <span style="color:#f2d5cf">profile</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ca9ee6">$(</span>basename <span style="color:#f2d5cf">$maildir</span><span style="color:#ca9ee6">)</span> </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">if</span> <span style="color:#99d1db;font-weight:bold">[</span> <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$profile</span><span style="color:#a6d189">&#34;</span> <span style="color:#99d1db;font-weight:bold">=</span> <span style="color:#a6d189">&#34;local&#34;</span> <span style="color:#99d1db;font-weight:bold">]</span>; <span style="color:#ca9ee6">then</span> </span></span><span style="display:flex;"><span> mlist <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">&#34;</span> | mthread -r -S <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">&#34;</span> | mseq -S </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">else</span> </span></span><span style="display:flex;"><span> mbsync -V <span style="color:#f2d5cf">$profile</span> </span></span><span style="display:flex;"><span> mlist <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">&#34;</span>/INBOX | mthread -r -S <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$sent</span><span style="color:#a6d189">&#34;</span> | mseq -S </span></span><span style="display:flex;"><span> minc <span style="color:#a6d189">&#34;</span><span style="color:#f2d5cf">$maildir</span><span style="color:#a6d189">/INBOX&#34;</span> &gt; /dev/null </span></span><span style="display:flex;"><span> <span style="color:#ca9ee6">fi</span> </span></span><span style="display:flex;"><span><span style="color:#99d1db;font-weight:bold">}</span> </span></span></code></pre></div><p>For the rest of usage of mblaze, I really recommend to use <code>man mblaze</code> since the software is really well documented, or you can also watch this <a href="https://piped.cronyakatsuki.xyz/watch?v=5YS8RPC4zwc">video</a> I took the inspiration from for this setup.</p> <h1 id="conclusion">Conclusion</h1> <p>Hope you have had a good read, and I hope you will maybe try out this mail setup, or create your own even better setup for your self.</p> Setup dns with adblock and dot/doh with pi-hole and unbound https://cronyakatsuki.xyz/blog/setup-dns-pihole-unbound/ 27-09-2023 https://cronyakatsuki.xyz/blog/setup-dns-pihole-unbound/ <p>Just another day I seted up my own private dns server that has adblocking ( and other stuff ) using pihole and uses unbound as a resolver. To safelly connect to the dns server I&rsquo;m using DNS over HTTPS for my browser&rsquo;s and HTTPS over TLS for stuffy for my whole desktop and private dns in android ( Android has DoH support but only for google and cloudflare right now). Let&rsquo;s get on to setting everything up</p> <!-- raw HTML omitted --> <h2 id="1-pihole">1. Pihole</h2> <p>Let&rsquo;s start with setting up pihole. I will be installing it with their script on a debian system for easier unbound integration ( unbound doesn&rsquo;t have an official docker container ).</p> <p>I recommend to read up on the pihole&rsquo;s docs on exactly how to install it since pihole get&rsquo;s frequent updates. <a href="https://docs.pi-hole.net/main/basic-install/">DOCS</a></p> <p>I recommend you to install the admin page for easier managmenet and ability to change the upstream dns server ( needed for changing it to unbound later on ). To be able to access the admin page I use an nginx configuration like this one.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#ca9ee6">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server_name</span> <span style="color:#a6d189">example.com</span> ; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">location</span> <span style="color:#a6d189">/</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">return</span> <span style="color:#ef9f76">403</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">location</span> <span style="color:#a6d189">/admin</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_pass</span> <span style="color:#a6d189">http://127.0.0.1:8185/admin</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">Host</span> <span style="color:#f2d5cf">$host</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># If you want to log user activity, comment these </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">access_log</span> <span style="color:#a6d189">/dev/null</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">error_log</span> <span style="color:#a6d189">/dev/null</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#a6d189">[::]:443</span> <span style="color:#a6d189">ssl</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">443</span> <span style="color:#a6d189">ssl</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">ssl_certificate</span> <span style="color:#a6d189">/etc/letsencrypt/live/example.com/fullchain.pem</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">ssl_certificate_key</span> <span style="color:#a6d189">/etc/letsencrypt/live/example.com/privkey.pem</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">include</span> <span style="color:#a6d189">/etc/letsencrypt/options-ssl-nginx.conf</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">ssl_dhparam</span> <span style="color:#a6d189">/etc/letsencrypt/ssl-dhparams.pem</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span>} </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">if</span> <span style="color:#a6d189">(</span><span style="color:#f2d5cf">$host</span> = <span style="color:#a6d189">example.com)</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">return</span> <span style="color:#ef9f76">301</span> <span style="color:#a6d189">https://</span><span style="color:#f2d5cf">$host$request_uri</span>; </span></span><span style="display:flex;"><span> } <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server_name</span> <span style="color:#a6d189">example.com</span> ; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">80</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#a6d189">[::]:80</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">return</span> <span style="color:#ef9f76">404</span>; <span style="color:#737994;font-style:italic"># managed by Certbot </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span>} </span></span></code></pre></div><p>The main point of this config is the <code>/admin</code> location that you need to pass the lighttpd port to acces the website, you can just do it on your main website also. Also to make lighttpd work with nginx listening on port 80 you need to edit the <code>server.port</code> to port you wan&rsquo;t to use in lighttpd config file located at <code>/etc/lighttpd/lighttpd.conf</code> and then just restart lighttpd</p> <h2 id="2-unbound">2. Unbound</h2> <p>For this part I will just link the pi-hole&rsquo;s unbound documentation because it is the most correct one and updated as things change regulary. <a href="https://docs.pi-hole.net/guides/dns/unbound/">Pi-hole unbound docs</a></p> <h2 id="3-dns-over-tls">3. DNS over TLS</h2> <p>For dns over tls you need to first have a ssl certificate. I recommend on using certbot to generate one with this command <code>certbot --nginx -d dot.example.com</code>.</p> <p>Next you will need a reverse proxy, in my case I use nginx. You will need to add this configuration to your main nginx config located at <code>/etc/nginx/nginx.conf</code>. <strong>Make sure to add this outside of the http block and change example.com to your domain</strong></p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#ca9ee6">stream</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">log_format</span> <span style="color:#a6d189">basic</span> <span style="color:#a6d189">&#39;</span><span style="color:#f2d5cf">$remote_addr</span> <span style="color:#a6d189">[</span><span style="color:#f2d5cf">$time_local]</span> <span style="color:#f2d5cf">$protocol</span> <span style="color:#f2d5cf">$status</span> <span style="color:#f2d5cf">$bytes_sent</span> <span style="color:#f2d5cf">$bytes_received</span> <span style="color:#f2d5cf">$session_time</span> <span style="color:#f2d5cf">$upstream_addr&#39;</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">upstream</span> <span style="color:#a6d189">dns</span> </span></span><span style="display:flex;"><span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">zone</span> <span style="color:#a6d189">dns</span> <span style="color:#ef9f76">64k</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server</span> 127.0.0.1:<span style="color:#ef9f76">53</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">853</span> <span style="color:#a6d189">ssl</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">access_log</span> <span style="color:#a6d189">/var/log/nginx/dot-access.log</span> <span style="color:#a6d189">basic</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">error_log</span> <span style="color:#a6d189">/var/log/nginx/dot-error.log</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_certificate</span> <span style="color:#a6d189">/etc/letsencrypt/live/dot.example.com/fullchain.pem</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_certificate_key</span> <span style="color:#a6d189">/etc/letsencrypt/live/dot.example.com/privkey.pem</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_protocols</span> <span style="color:#a6d189">TLSv1.2</span> <span style="color:#a6d189">TLSv1.3</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_ciphers</span> <span style="color:#a6d189">HIGH:!aNULL:!MD5</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_handshake_timeout</span> <span style="color:#a6d189">10s</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_session_cache</span> <span style="color:#a6d189">shared:SSL:20m</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_session_timeout</span> <span style="color:#a6d189">4h</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_pass</span> <span style="color:#a6d189">dns</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_responses</span> <span style="color:#ef9f76">1</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_timeout</span> <span style="color:#a6d189">1s</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Also make sure to enable port 853, example ufw command is <code>ufw allow 853/tcp</code>. Then restart nginx, to test if this configuration is working you can use your android phone by setting the private dns address to <code>dot.example.com</code> and then visit the website<a href="https://dnsleaktest.com">dnsleaktest</a></p> <h2 id="4-dns-over-https">4. DNS over HTTPS</h2> <p>For using dns over https we will be installing additional package called dnsdinst. On debian systems just run <code>apt install dnsdinst</code>. Next you will need to setup dnsdinst config and restart it. Make sure to change example.com.</p> <pre tabindex="0"><code class="language-conf" data-lang="conf">-- dnsdist configuration file, an example can be found in /usr/share/doc/dnsdist/examples/ -- disable security status polling via DNS setSecurityPollSuffix(&#34;&#34;) -- fix up possibly badly truncated answers from pdns 2.9.22 -- truncateTC(true) -- Answer to only clients from this subnet setACL(&#34;127.0.0.1/8&#34;) -- Define upstream DNS server (Pi-hole) newServer({address=&#34;127.0.0.1&#34;, name=&#34;Pi-hole&#34;, checkName=&#34;example.com&#34;, checkInterval=60, mustResolve=true}) -- Create local DOH server listener in DNS over HTTP mode, otherwise the information coming from nginx won&#39;t be processed well addDOHLocal(&#34;127.0.0.1:5300&#34;, nil, nil, &#34;/dns-query&#34;, { reusePort=true }) </code></pre><p>Next we will need another ssl certificate for the doh domain, for that we will once again using certbot with this command <code>certbot --nginx -d doh.example.com</code>after that add this configuratin to nginx either in sites-available and linking it to sites enabled or in http block in main nginx configuration.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Proxy Cache storage - so we can cache the DoH response from the upstream </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span><span style="color:#ca9ee6">proxy_cache_path</span> <span style="color:#a6d189">/var/run/doh_cache</span> <span style="color:#a6d189">levels=1:2</span> <span style="color:#a6d189">keys_zone=doh_cache:10m</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#ca9ee6">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">80</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server_name</span> <span style="color:#a6d189">doh.example.com</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">return</span> <span style="color:#ef9f76">301</span> <span style="color:#a6d189">https://doh.example.com/</span><span style="color:#f2d5cf">$request_uri</span>; </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># This virtual server accepts HTTP/2 over HTTPS </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span><span style="color:#ca9ee6">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">443</span> <span style="color:#a6d189">ssl</span> <span style="color:#a6d189">http2</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server_name</span> <span style="color:#a6d189">doh.example.com</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">access_log</span> <span style="color:#a6d189">/var/log/nginx/doh.access</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">error_log</span> <span style="color:#a6d189">/var/log/nginx/doh.error</span> <span style="color:#a6d189">error</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_certificate</span> <span style="color:#a6d189">/etc/letsencrypt/live/doh.example.com/fullchain.pem</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_certificate_key</span> <span style="color:#a6d189">/etc/letsencrypt/live/doh.example.com/privkey.pem</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># DoH may use GET or POST requests, Cache both </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">proxy_cache_methods</span> <span style="color:#a6d189">GET</span> <span style="color:#a6d189">POST</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># Return 404 to all responses, except for those using our published DoH URI </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">location</span> <span style="color:#a6d189">/</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">try_files</span> <span style="color:#f2d5cf">$uri</span> <span style="color:#f2d5cf">$uri/</span> =<span style="color:#ef9f76">404</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">ssl_protocols</span> <span style="color:#a6d189">TLSv1.2</span> <span style="color:#a6d189">TLSv1.3</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_ssl_ciphers</span> <span style="color:#a6d189">HIGH:!aNULL:!MD5</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># This is our published DoH URI </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">location</span> <span style="color:#a6d189">/dns-query</span> { </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># Proxy HTTP/1.1, clear the connection header to enable Keep-Alive </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">proxy_http_version</span> <span style="color:#ef9f76">1</span><span style="color:#a6d189">.1</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">Connection</span> <span style="color:#a6d189">&#34;&#34;</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># Enable Cache, and set the cache_key to include the request_body </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">proxy_cache</span> <span style="color:#a6d189">doh_cache</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_cache_key</span> <span style="color:#f2d5cf">$scheme$proxy_host$uri$is_args$args$request_body</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># proxy pass to dnsdist </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">proxy_pass</span> <span style="color:#a6d189">http://127.0.0.1:5300</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#737994;font-style:italic"># proxy pass address </span></span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"></span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">X-Forwarded-For</span> <span style="color:#f2d5cf">$proxy_add_x_forwarded_for</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>After restarting nginx with this configuration you can it to your web browser as a DNS over HTTPS resolver and once again checkout <a href="https://dnsleaktest.com">dnsleaktest</a> website and check if it is all working.</p> <p>Hope this has been helpfull and if anybody has any way on how to make this guied better you can open a pull request or make an issue on the website&rsquo;s <a href="https://code.cronyakatsuki.xyz/crony/website">repo</a>.</p> Piped videos not loading https://cronyakatsuki.xyz/blog/piped-video-not-loading/ 26-02-2023 https://cronyakatsuki.xyz/blog/piped-video-not-loading/ <p>Recently I have received and experienced an issue of videos not loading on my personal <a href="https://piped.cronyakatsuki.xyz">piped</a> instance and on the official instance. But I have found a fix and a way to watch the videos even without the fix.</p> <!-- raw HTML omitted --> <h2 id="what-creates-the-issue">What creates the issue?</h2> <p>From what I have been able to find on the issues over on the <a href="https://github.com/TeamPiped/Piped">piped github</a> it seems to be an lbry issue of the videos not loading mostly on firefox, the issue seems to not happen on the chromium browsers.</p> <h3 id="how-to-fix-the-issue">How to fix the issue</h3> <p>To fix the issue you just have to enable an option in the instance settings called <code>disable lbry for streaming</code>. This will disable loading of lbry for videos and the issue will mostly just be bypassed.</p> <h3 id="fun-way-to-also-watch-the-videos">Fun way to also watch the videos</h3> <p>If you are like me and bored you can also watch the videos without using the fix by opening the firefox debug console, and in the errors you will see the link of the video that the frontend wasn&rsquo;t able to embed. Just click the link and you will be able to watch the video or it will say that the content isn&rsquo;t reachable and then you will need to do the fix otherwise it&rsquo;s a no no to watch that video otherwise.</p> miniflux setup on debian https://cronyakatsuki.xyz/blog/miniflux-setup/ 30-11-2022 https://cronyakatsuki.xyz/blog/miniflux-setup/ <p>Looking for a minimal self-hosted feed reader I found <a href="https://miniflux.app/">miniflux</a>. But trying to set it up I found my self trying to set it up for 3 freaking hours since I only recently started to self-host things. So here I will try to explaing it in the most easy way how to set it up on a debian server with https using certbot and nginx.</p> <!-- raw HTML omitted --> <p>For this tutorial I expect that you already have a server seted up with nginx and certbot. To set up this things check out <a href="https://landchad.net">landchad</a></p> <h2 id="installing-needed-packages">Installing needed packages</h2> <p>You will first need to setup miniflux apt repository to install it on your system.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#99d1db">echo</span> <span style="color:#a6d189">&#34;deb [trusted=yes] https://repo.miniflux.app/apt/ /&#34;</span> | sudo tee /etc/apt/sources.list.d/miniflux.list &gt; /dev/null </span></span><span style="display:flex;"><span>apt update </span></span></code></pre></div><p>Then just install the needed packages.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apt install miniflux postgresql </span></span></code></pre></div><h2 id="setting-up-postgres-database-and-miniflux">Setting up postgres database and miniflux</h2> <p>Here I will detail steps to create the postgres database.</p> <h3 id="initial-postgres-setup">Initial postgres setup</h3> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Switch to the postgres user</span> </span></span><span style="display:flex;"><span>$ su - postgres </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Creating a miniflux user, enter a safe and secure password</span> </span></span><span style="display:flex;"><span>$ createuser -P miniflux </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Create a database for miniflux that belongs to our user</span> </span></span><span style="display:flex;"><span>$ createdb -O miniflux miniflux </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Create a database for miniflux that belongs to our user</span> </span></span><span style="display:flex;"><span>$ createdb -O miniflux miniflux </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Creating extension hstore as superuser</span> </span></span><span style="display:flex;"><span>$ psql miniflux -c <span style="color:#a6d189">&#39;create extension hstore&#39;</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Managing the miniflux database</span> </span></span><span style="display:flex;"><span>$ psql <span style="color:#f2d5cf">$MINIFLUX_DATABASE</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Giving miniflux user all privileges</span> </span></span><span style="display:flex;"><span>&gt; alter user miniflux with superuser; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Exit the postgres database</span> </span></span><span style="display:flex;"><span>&gt; <span style="color:#8caaee">\q</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Exit postgres user</span> </span></span><span style="display:flex;"><span>$ <span style="color:#99d1db">exit</span> </span></span></code></pre></div><h3 id="miniflux-configuration-file">Miniflux configuration file</h3> <p>Open the miniflux configuration file in path <code>/etc/miniflux.conf</code> and edit it like this.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># See https://miniflux.app/docs/configuration.html</span> </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">LISTEN_ADDR</span><span style="color:#99d1db;font-weight:bold">=</span>127.0.0.1:8080 </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">DATABASE_URL</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#f2d5cf">user</span><span style="color:#99d1db;font-weight:bold">=</span>miniflux <span style="color:#f2d5cf">password</span><span style="color:#99d1db;font-weight:bold">=</span>PASSWORD_HERE <span style="color:#f2d5cf">dbname</span><span style="color:#99d1db;font-weight:bold">=</span>miniflux <span style="color:#f2d5cf">sslmode</span><span style="color:#99d1db;font-weight:bold">=</span>disable </span></span><span style="display:flex;"><span><span style="color:#f2d5cf">RUN_MIGRATIONS</span><span style="color:#99d1db;font-weight:bold">=</span><span style="color:#ef9f76">1</span> </span></span></code></pre></div><h3 id="migrating-the-database-and-removing-superuser-privileges-in-postgres">Migrating the database and removing superuser privileges in postgres</h3> <p>Now we will migrate the database and remove unneded superuser privileges, since it is reccomended in the miniflux documentation.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Migrating the database</span> </span></span><span style="display:flex;"><span>$ miniflux -c /etc/miniflux.conf -migrate </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Creating miniflux admin user</span> </span></span><span style="display:flex;"><span>$ miniflux -c /etc/miniflux.conf -create-admin </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Restarting the systemctl service</span> </span></span><span style="display:flex;"><span>$ systemctl restart miniflux </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Entering postgres database user</span> </span></span><span style="display:flex;"><span>$ su - postgres </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Entering miniflux database</span> </span></span><span style="display:flex;"><span>$ psql <span style="color:#f2d5cf">$MINIFLUX_DATABASE</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Removing unneded superuser privileges from miniflux user</span> </span></span><span style="display:flex;"><span>&gt; alter user miniflux with nosuperuser; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Exit the postgres database</span> </span></span><span style="display:flex;"><span>&gt; <span style="color:#8caaee">\q</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#737994;font-style:italic"># Exit postgres user</span> </span></span><span style="display:flex;"><span>$ <span style="color:#99d1db">exit</span> </span></span></code></pre></div><h2 id="nginx-and-certbot-setup">Nginx and certbot setup</h2> <p>Make sure to have a domain to use for your miniflux setup.</p> <p>Create and open a nginx config with path <code>/etc/nginx/sites-available/miniflux.conf</code> and add this</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#ca9ee6">server</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">server_name</span> <span style="color:#a6d189">your.domain.ext</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#ef9f76">80</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">listen</span> <span style="color:#a6d189">[::]:80</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#81c8be">location</span> <span style="color:#a6d189">/</span> { </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_pass</span> <span style="color:#a6d189">http://127.0.0.1:8080</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_redirect</span> <span style="color:#e5c890">off</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">Host</span> <span style="color:#f2d5cf">$host</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">X-Real-IP</span> <span style="color:#f2d5cf">$remote_addr</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">X-Forwarded-For</span> <span style="color:#f2d5cf">$proxy_add_x_forwarded_for</span>; </span></span><span style="display:flex;"><span> <span style="color:#81c8be">proxy_set_header</span> <span style="color:#a6d189">X-Forwarded-Proto</span> <span style="color:#f2d5cf">$scheme</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Now just link the config to enabled sites and restart nginx service.</p> <div class="highlight"><pre tabindex="0" style="color:#c6d0f5;background-color:#303446;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ ln -s /etc/nginx/sites-available/miniflux.conf /etc/nginx/sites-enabled/miniflux.conf </span></span><span style="display:flex;"><span>$ systemctl restart nginx </span></span></code></pre></div><p>To get https on your domain you just need to run <code>certbot --nginx</code> same as in this <a href="https://landchad.net/basic/certbot/">tutorial</a></p> <h2 id="finishing-words">Finishing words</h2> <p>I hope that this wasn&rsquo;t hard to follow and shouldn&rsquo;t take hours like it took me first time I tried to set this all up.</p>