<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Marco's Corner]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://marcoperetti.com/</link><image><url>https://marcoperetti.com/favicon.png</url><title>Marco&apos;s Corner</title><link>https://marcoperetti.com/</link></image><generator>Ghost 5.69</generator><lastBuildDate>Sat, 13 Jun 2026 08:12:25 GMT</lastBuildDate><atom:link href="https://marcoperetti.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Monitoring per-device traffic on FritzBox]]></title><description><![CDATA[<p>A common complain from FritzBox customers is that you cannot monitor traffic on a per-device basis, as FritzBox only shows a combined view of downstream and upstream traffic. If you are after per-device traffic, you typically have to  configure your FritzBox to capture traffic (in PCAP format) and then use</p>]]></description><link>https://marcoperetti.com/monitoring-per-device-traffic-on-fritzbox/</link><guid isPermaLink="false">6679c21207e593000155c3b2</guid><dc:creator><![CDATA[Marco]]></dc:creator><pubDate>Mon, 24 Jun 2024 19:55:50 GMT</pubDate><content:encoded><![CDATA[<p>A common complain from FritzBox customers is that you cannot monitor traffic on a per-device basis, as FritzBox only shows a combined view of downstream and upstream traffic. If you are after per-device traffic, you typically have to  configure your FritzBox to capture traffic (in PCAP format) and then use something like NTOP to visualize it.</p><p><a href="https://en.avm.de/fritz-lab/fresh-from-development/fresh-from-development/?ref=marcoperetti.com" rel="noreferrer">Fritz!OS 7.90</a> (beta) finally changes that, as it brings &quot;New graphic Online Monitor informs about the utilization of the internet connection and on the utilization by individual network devices&quot;. </p><p>As it is still in beta, you need to download the beta version and upgrade manually following the procedure described <a href="https://en.avm.de/fritz-lab/fresh-from-development/fresh-from-development/?ref=marcoperetti.com" rel="noreferrer">here</a> . Simply select the correct version for your FritzBox and make sure to unzip the file once downloaded.</p><p>Once installed and rebooted, you will see the new UI under Internet-&gt;Online monitoring.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2024/06/fritz---total-view.png" class="kg-image" alt loading="lazy" width="1884" height="715" srcset="https://marcoperetti.com/content/images/size/w600/2024/06/fritz---total-view.png 600w, https://marcoperetti.com/content/images/size/w1000/2024/06/fritz---total-view.png 1000w, https://marcoperetti.com/content/images/size/w1600/2024/06/fritz---total-view.png 1600w, https://marcoperetti.com/content/images/2024/06/fritz---total-view.png 1884w" sizes="(min-width: 720px) 720px"></figure><p>The Individual Devices view will be empty, as you first need to explicitly select the devices for which you&apos;ll track the traffic. </p><p>Pick the device(s) of interest from Home Network -&gt; Network and edit the properties to include &quot;Save internet data rates for this device&quot; as shown below.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2024/06/fritz---option.png" class="kg-image" alt loading="lazy" width="814" height="133" srcset="https://marcoperetti.com/content/images/size/w600/2024/06/fritz---option.png 600w, https://marcoperetti.com/content/images/2024/06/fritz---option.png 814w" sizes="(min-width: 720px) 720px"></figure><p>You can now return to the Online Monitor and click on Individual Devices tab. The Adjust Selection button allows you to chose the device(s) you wish to monitor. In this example, we are going to select a Samsung device but remember that you can select multiple devices.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2024/06/fritz---adjust-selection.png" class="kg-image" alt loading="lazy" width="847" height="954" srcset="https://marcoperetti.com/content/images/size/w600/2024/06/fritz---adjust-selection.png 600w, https://marcoperetti.com/content/images/2024/06/fritz---adjust-selection.png 847w" sizes="(min-width: 720px) 720px"></figure><p>You should now be able to finally see per-device downstream and upstream traffic, without the need to install additional software.</p><p></p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2024/06/frtiz---individual-devices.png" class="kg-image" alt loading="lazy" width="1900" height="838" srcset="https://marcoperetti.com/content/images/size/w600/2024/06/frtiz---individual-devices.png 600w, https://marcoperetti.com/content/images/size/w1000/2024/06/frtiz---individual-devices.png 1000w, https://marcoperetti.com/content/images/size/w1600/2024/06/frtiz---individual-devices.png 1600w, https://marcoperetti.com/content/images/2024/06/frtiz---individual-devices.png 1900w" sizes="(min-width: 720px) 720px"></figure><p>The view is fairly simple, but still useful when you need to inspect bandwidth usage on a per-device basis.</p>]]></content:encoded></item><item><title><![CDATA[Setting up Ghost on your home server and Dynamic IP - 2023 Edition]]></title><description><![CDATA[<p></p><p>Look Ma! No Static IP!</p><p>In this article, I am going to show you how to self-host a blogging solution like Ghost with a dynamic IP address. The solution applies to pretty much anything served by a web server.</p><p>I added <strong>2023 Edition</strong> to the title as most guides I&</p>]]></description><link>https://marcoperetti.com/setting-up-ghost-on-dynamic-ip/</link><guid isPermaLink="false">6530e6cb1c1e1c0001865cd0</guid><dc:creator><![CDATA[Marco]]></dc:creator><pubDate>Thu, 19 Oct 2023 20:42:13 GMT</pubDate><content:encoded><![CDATA[<p></p><p>Look Ma! No Static IP!</p><p>In this article, I am going to show you how to self-host a blogging solution like Ghost with a dynamic IP address. The solution applies to pretty much anything served by a web server.</p><p>I added <strong>2023 Edition</strong> to the title as most guides I&apos;ve found where a little older and somewhat obsolete. </p><p>I use <a href="https://www.cloudflare.com/?ref=marcoperetti.com" rel="noreferrer">Cloudflare&apos;s</a> services, but there are other solutions around. If you don&apos;t have a Cloudflare account yet, now is a good time to create one. For testing purposes or hosting a simple blog like this one the Free plan will suffice, providing much needed protection and caching, for free.  </p><p> Here&apos;s a brief summary of what I am going to cover:</p><ul>
<li>Set up Ghost on Docker using Docker Compose</li>
<li>Add a Cloudflare Site, with your domain</li>
<li>Set up a Cloudflare Tunnel</li>
<li>Have the domain indexed by Google</li>
<li>Security considerations</li>
</ul>
<p>I assume you have a domain name available you can use, have Docker and Docker Compose installed and know how to use the command line. If not, this guide is most probably not for you.</p><h2 id="set-up-ghost">Set up Ghost</h2><p>Ghost can be installed on many <a href="https://ghost.org/docs/install/?ref=marcoperetti.com" rel="noreferrer">platforms</a> in different ways. Here, we will use Docker and Docker Compose using the following YAML file:</p><pre><code class="language-yaml">version: &apos;3.1&apos;

services:
  ghost:
    image: ghost:latest
    restart: always
    ports:
      - &apos;2368:2368&apos;
    networks:
      - internal_ghost
    dns:
      - 8.8.8.8
    volumes:
      - /home/&lt;USER&gt;/blog/&lt;YOURDOMAIN&gt;/ghostblog/ghostdata:/var/lib/ghost/content
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: &lt;COMPLEX_PASSWORD&gt;
      database__connection__database: db
      mail__transport: SMTP
      mail__from: &lt;YOURNAME&gt;@gmail.com
      mail__options__port: 465
      mail__options__secure: true
      mail__options__host: smtp.gmail.com
      mail__options__service: Google
      mail__options__auth__user: YOURNAME@gmail.com
      mail__options__auth__pass: GOOGLE_APP_PASSWORD
      url: https://&lt;YOURDOMAIN&gt;.com

  db:
    image: mariadb:latest
    restart: always
    networks:
      - internal_ghost
    volumes:
     - /home/&lt;USER&gt;/blog/&lt;YOURDOMAIN&gt;/ghostblog/sqldata:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: &lt;COMPLEX_PASSWORD&gt;
      MYSQL_DATABASE: db
      MYSQL_USER: root
      MYSQL_PASSWORD: &lt;COMPLEX_PASSWORD&gt;

networks:
  internal_ghost:
    external: true</code></pre><p>One of the problems I faced setting up Ghost is that it requires a mail server for new accounts registrations and sending out bulk emails for the newsletter. As of October 2023, the only official integration for bulk emails is Mailgun.</p><p>Mailgun used to have a free plan but now it costs 35$/month. As I have no need for a newsletter, I used my personal gmail account to send out emails for new accounts registrations.  </p><p>A few notes about the YAML file above.</p><ul>
<li>Uppercase names within angle brackets must be replaced with suitable values. For example, I replaced &lt;YOURDOMAIN&gt; with marcoperetti</li>
<li>The path for the data and sql volumes need to be modified for your environment. The above works on Ubuntu 22.04, as long as the corresponding directories have been created.</li>
<li>Replace YOURNAME with your gmail user name</li>
<li><a href="https://myaccount.google.com/apppasswords?ref=marcoperetti.com">Generate an app password for Gmail</a> and replace GOOGLE_APP_PASSWORD</li>
<li>Replace COMPLEX_PASSWORD with ... something else</li>
<li>Replace YOURDOMAIn with the name of your domain</li>
</ul>
<p>Save the YAML in a file named <strong>docker-compose.yml</strong> and copy it to  /home/&lt;USER&gt;/blog/&lt;YOURDOMAIN&gt;. </p><p>Our Docker network is named internal_ghost, and must be created by running <strong>docker network create internal_ghost</strong>.</p><p>From the &lt;yourdomain&gt; directory, run <strong>docker compose up -d</strong></p><p>The first time it will take some time as it needs to download the necessary images. Before moving to the next step, I suggest you check that Ghost has been set up correctly by checking the logs.</p><p>Run <strong>docker ps</strong> to obtain the container IDs, and then <strong>docker logs &lt;container id&gt;</strong> to see the logs. There should be no errors. </p><h2 id="add-a-cloudflare-site">Add a Cloudflare site</h2><p>In order to set up a tunnel we must first add a site.</p><p>Log on to Cloudflare and click on <strong>Add a site</strong> from the <a href="https://dash.cloudflare.com/?ref=marcoperetti.com" rel="noreferrer">dashboard</a>. You will be requested to either provide the name of an existing  domain name, or register a new domain directly from Cloudflare. As I had mine registered on Namecheap.com, I entered the name and clicked on Continue.</p><p>At this point you will be presented with the different plans. Chose what makes sense to you, but for testing purposes or personal blog sites the <strong>Free plan</strong> will suffice.  </p><p>Cloudflare will then copy over the existing DNS configuration,  and will provide suggestions. I am assuming the domain is not used for anything else, and most records can be discarded. You may want to keep the TXT records.</p><p><strong>Note</strong>: If you are unfamiliar with DNS and are using the domain for other purposes, I suggest you proceed with extreme care, or not at all. I cannot guess your configuration and  cannot take any responsibility for any misconfiguration, nor help you in case you screw it ip. </p><p>If you decide to proceed, click on Continue and you will be asked to change the DNS Servers to Cloudflare&apos;s. On Namecheap, select the domain from the dashboard, select &quot;Custom DNS&quot; from the <strong>Nameservers</strong> section, and add the names provided by Cloudflare. Click on Done, and wait for the changes to take effect. </p><p><strong>Note</strong>: there is no need to transfer over the domain to Cloudflare. If you wish to do so, follow these <a href="https://developers.cloudflare.com/registrar/get-started/transfer-domain-to-cloudflare/?ref=marcoperetti.com" rel="noreferrer">instructions</a>. </p><p>If all goes well, you should see in the dashboard that your Cloudflare site is <strong>active</strong> as shown below.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-21.01.18.png" class="kg-image" alt loading="lazy" width="634" height="107" srcset="https://marcoperetti.com/content/images/size/w600/2023/10/Screenshot-2023-10-19-at-21.01.18.png 600w, https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-21.01.18.png 634w"></figure><h2 id="set-up-cloudflare-tunnel">Set up Cloudflare Tunnel</h2><p>You now have to decide how to make your Ghost server instance accessible to the public internet. This could be achieved by installing NGNIX, generate LetsEncrypt certificates, and opening port 443 on your router. </p><p>The alternative, is to use Cloudflare Tunnel, which  takes care of tunneling traffic, without the need to open any port. Cloudflare Tunnel  requires the deployment of an agent on your server, and we will see shortly the various options. </p><p>From your site dashboard, click on <strong>Access</strong> to access the Cloudflare Zero Trust site. Once there, select Access from the left menu, then Tunnels. There you will see the list of Tunnels and the option to create a new tunnel.</p><p>Click on Create Tunnel and give it a name. Once Saved, you will be presented with the instructions to deploy the agent, as shown below.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.09.40.png" class="kg-image" alt loading="lazy" width="1191" height="586" srcset="https://marcoperetti.com/content/images/size/w600/2023/10/Screenshot-2023-10-19-at-22.09.40.png 600w, https://marcoperetti.com/content/images/size/w1000/2023/10/Screenshot-2023-10-19-at-22.09.40.png 1000w, https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.09.40.png 1191w" sizes="(min-width: 720px) 720px"></figure><p>Install the agent on the computer  running Ghost and then click on Next to set up the route, that is, how the traffic from your public hostname (the domain) will reach Ghost on your server. </p><p>As we will be serving the blog from the root domain, it should look like the one below.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.14.14.png" class="kg-image" alt loading="lazy" width="1303" height="600" srcset="https://marcoperetti.com/content/images/size/w600/2023/10/Screenshot-2023-10-19-at-22.14.14.png 600w, https://marcoperetti.com/content/images/size/w1000/2023/10/Screenshot-2023-10-19-at-22.14.14.png 1000w, https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.14.14.png 1303w" sizes="(min-width: 720px) 720px"></figure><p>If all goes well, the tunnel&apos;s status should be HEALTHY </p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.22.45.png" class="kg-image" alt loading="lazy" width="1066" height="135" srcset="https://marcoperetti.com/content/images/size/w600/2023/10/Screenshot-2023-10-19-at-22.22.45.png 600w, https://marcoperetti.com/content/images/size/w1000/2023/10/Screenshot-2023-10-19-at-22.22.45.png 1000w, https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.22.45.png 1066w" sizes="(min-width: 720px) 720px"></figure><p>In your DNS records, you should see a new CNAME record, which links the root domain to the tunnel.</p><figure class="kg-card kg-image-card"><img src="https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.25.03.png" class="kg-image" alt loading="lazy" width="1188" height="51" srcset="https://marcoperetti.com/content/images/size/w600/2023/10/Screenshot-2023-10-19-at-22.25.03.png 600w, https://marcoperetti.com/content/images/size/w1000/2023/10/Screenshot-2023-10-19-at-22.25.03.png 1000w, https://marcoperetti.com/content/images/2023/10/Screenshot-2023-10-19-at-22.25.03.png 1188w" sizes="(min-width: 720px) 720px"></figure><p>You should now be able to access your Ghost instance from https://yourdomain.com</p><p>The last step is to redirect www to your root domain. Follow this simple <a href="https://developers.cloudflare.com/pages/how-to/www-redirect/?ref=marcoperetti.com" rel="noreferrer">guide</a> and you should be set. Just remember that it takes time to propagate DNS changes and it may not work immediately - be patient and give it some time to propagate. </p><p>If you have never used Ghost before, you need to begin by accessing  the admin portal under https://yourdomain.com/ghost. Follow this <a href="https://ghost.org/resources/how-to-setup-your-ghost-publication/?ref=marcoperetti.com" rel="noreferrer">guide</a> for additional details on first-time settings.</p><p>I also suggest ensuring that accounts signup work. Subscribe as a regular user (from the root domain) . Both the user and yourself, the admin, should receive an email. In my case, as there is not much content yet, I decided to disable new users&apos; signup - one less thing to worry about. </p><p>So by now you should have your blog up and running, but Google isn&apos;t aware of it, and you won&apos;t get much traffic, if any at all - well, except malicious traffic, that is.</p><h2 id="have-the-domain-indexed-by-google">Have the domain indexed by Google</h2><p>The tool to let Google know about your web site is the <a href="https://search.google.com/search-console/about?ref=marcoperetti.com" rel="noreferrer">Google Search Console</a>.</p><p>You basically need to prove that you own the domain, and you are going to prove it by <strong>adding a Domain property </strong>from the menu, which will require prof of ownership by means of <a href="https://support.google.com/webmasters/answer/34592?ref=marcoperetti.com" rel="noreferrer">DNS record verification</a>. </p><p>Once verified, you should submit your sitemap, which is basically a url that looks like https://yourdomain.com/sitemap.xml, and Google will add it the queue of sites to be crawled.</p><h2 id="security-considerations">Security Considerations</h2><p>Self-hosting is not without risks, even for a well locked-down environment. Here are some basic suggestions to get you started:</p><ul><li>Ensure that Docker is not running as <a href="https://docs.docker.com/engine/security/rootless/?ref=marcoperetti.com" rel="noreferrer">root</a>.  </li><li>Secure the /ghost admin panel with Cloudflare Teams. I used this <a href="https://alexgallacher.com/how-to-configure-cloudflare-tunnels-for-a-secure-ghost-blog/?ref=marcoperetti.com" rel="noreferrer">guide</a>.</li><li>Consider disabling new <a href="https://ghost.org/help/can-i-disable-memberships/?ref=marcoperetti.com" rel="noreferrer">users sign-ups</a>. </li><li>Learn how to back-up, upgrade and restore your site. </li><li>Subscribe to Ghost <a href="https://ghost.org/changelog/?ref=marcoperetti.com" rel="noreferrer">Changelog</a> newsletter to be notified abut product updates</li></ul><p>Happy blogging.</p>]]></content:encoded></item></channel></rss>