<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Daniel Anomfueme - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Daniel Anomfueme - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:24:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/LifeofDan-EL/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Public Grafana-based Solar Monitoring Dashboard in Home Assistant ]]>
                </title>
                <description>
                    <![CDATA[ If you have a solar inverter setup, one thing you would agree on with me is that data from your solar inverter setup is really important. Another thing that is also important is having a way to show what your energy generation, consumption, and so on... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-public-grafana-based-solar-monitoring-dashboard-in-home-assistant/</link>
                <guid isPermaLink="false">68010bea439877985a5bf3e2</guid>
                
                    <category>
                        <![CDATA[ iot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Home Assistant ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Grafana ]]>
                    </category>
                
                    <category>
                        <![CDATA[ InfluxDB ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solar energy ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Anomfueme ]]>
                </dc:creator>
                <pubDate>Thu, 17 Apr 2025 14:10:50 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744899028552/8ad3f3c4-9b25-473d-b539-14dcb2f2b241.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you have a solar inverter setup, one thing you would agree on with me is that data from your solar inverter setup is really important. Another thing that is also important is having a way to show what your energy generation, consumption, and so on looks like publicly.</p>
<p>The thing is that most solar inverter brands have a form of remote data monitoring platform, from <a target="_blank" href="https://www.victronenergy.com/panel-systems-remote-monitoring/vrm">Victron’s VRM</a> to <a target="_blank" href="https://en.growatt.com/products/growatt-monitoring-platform">Growatt’s ShineServe</a>r to <a target="_blank" href="https://www.deyeinverter.com/product/accessory-monitoring-1/smart-pv-management-platform.html">Deye’s Cloud</a>, among others. But I’m a fan of self-hosting and local control of data. This is one of the best ways to visualize and showcase all that beautiful data you have publicly to fellow tinkerers, solar inverter users, and the general public without relying on the company’s cloud data logger solution.</p>
<p>In this article, we will be using data available in our Home Assistant setup, sending it to <a target="_blank" href="https://www.influxdata.com/products/influxdb/">InfluxDB</a> and making a <a target="_blank" href="https://grafana.com/oss/grafana/">Grafana</a> dashboard out of it. There are a good number of ways to connect your inverter to Home Assistant, depending on the manufacturer. I use a Growatt SPF ES 6000 inverter, and I shared a guide on how to make a local data logger for it that works with Home Assistant <a target="_blank" href="https://hackernoon.com/turn-your-dumb-solar-inverter-into-a-smart-one-with-this-home-assistant-hack">here</a>.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-and-configure-influxdb">How to Install and Configure InfluxDB</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-and-configure-grafana">How to Install and Configure Grafana</a></p>
</li>
<li><p><a class="post-section-overview" href="#how-to-create-the-grafana-solar-dashboard">How to Create the Grafana Solar Dashboard</a></p>
</li>
<li><p><a class="post-section-overview" href="#how-to-create-a-new-admin-user-and-delete-the-default-admin-user">How to Create a New Admin User and Delete the Default Admin User</a></p>
</li>
<li><p><a class="post-section-overview" href="#how-to-enable-remote-access-to-the-solar-dashboard">How to Enable Remote Access to the Solar Dashboard</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<ul>
<li><p>Home Assistant OS</p>
</li>
<li><p>A domain name</p>
</li>
<li><p>An inverter connected to your Home Assistant instance</p>
</li>
</ul>
<h2 id="heading-how-to-install-and-configure-influxdb">How to Install and Configure InfluxDB</h2>
<p>We will be starting by setting up InfluxDB. InfluxDB is an open-source time series database, which differs from the database that <a target="_blank" href="https://www.home-assistant.io/docs/backend/database/#:~:text=The%20default%20database%20used%20is,other%20databases%20can%20be%20used.">Home Assistant uses by default</a>, SQLite. We will be using InfluxDB v1, as it’s much easier to set up.</p>
<p>Go to your Home Assistant dashboard and go to Settings &gt; Add-ons and click on the Add-On Store.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744463486874/9dda1fca-24a9-4c30-a486-3b723e8535fe.png" alt="A screenshot of Home Assistant Add-ons" class="image--center mx-auto" width="1713" height="1378" loading="lazy"></p>
<p>Inside the Add-on Store, search for “InfluxDB“ and click on the Add-on. You should see the screen below, then install.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744463639772/75f66c35-e7b3-4c20-96ea-9e9154829ac5.png" alt="A screenshot of Home Assistant Add-ons, showing InfluxDB Add-on page" class="image--center mx-auto" width="1703" height="1350" loading="lazy"></p>
<p>Toggle the “Watchdog” on, as this allows the add-on to restart if it crashes. Also, toggle the “show in sidebar” on, which allows you to see the add-on on Home Assistant’s sidebar.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744465515531/0c9e9475-08c2-4bc3-afe5-baa4fdbae164.png" alt="A screenshot of InfluxDB Add-on installed and some configurations turned on" class="image--center mx-auto" width="1698" height="1252" loading="lazy"></p>
<p>Start the add-on and look at the logs to be sure it is working. The “Starting NGINX” is an indicator it’s working.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744465746577/f3adbd52-14cd-4e78-b2d7-789ad2c22b31.png" alt="A screenshot of InfluxDB Add-on logs" class="image--center mx-auto" width="1721" height="1246" loading="lazy"></p>
<p>Next, go to your Home Assistant sidebar and click on InfluxDB. You need to create a new database to hold your data and also create a new user that has admin privileges to read and write data. Go to the InfluxDB Admin tab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744466323654/78f21741-e6ca-4094-8fc3-adc563b3dfc1.png" alt="A screenshot of InfluxDB Add-on Admin settings showing database available" class="image--center mx-auto" width="1722" height="1367" loading="lazy"></p>
<p>Click on Create Database – and you can name the database anything you want. I will be naming mine <strong>homeassistant</strong>.</p>
<p>By default, the retention policy for a created database is infinity (which is forever), but you can configure this to be any time frame you want. Retention policy refers to the time frame of data the database can hold. I prefer to stick with infinity as I want to keep as much data as possible and I have enough storage in my Home Assistant hardware for that.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744466625066/c2ae2012-44d8-4acb-91ae-25ad35fb18ff.png" alt="A screenshot of InfluxDB Add-on Admin settings showing the newly created database available" class="image--center mx-auto" width="1725" height="1350" loading="lazy"></p>
<p>Once the database is created, go to the Users tab so you can create the new admin user. Input a username and password for that user and click on Grant Admin, so the permission level can be set to all. I created a new user called <strong>root</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744467230710/6c025cb7-123a-4552-8090-6a9550e64ecf.png" alt="A screenshot of InfluxDB Add-on Admin settings showing users available" class="image--center mx-auto" width="1712" height="1350" loading="lazy"></p>
<p>At this point, what is left on the InfluxDB side is to tell Home Assistant to start sending sensor data to InfluxDB. You can do this by going to your Home Assistant <strong>configuration.yaml</strong> file and adding this config below to it. Your host is the IP of your Home Assistant, the port is the default port for the InfluxDB add-on, and the remaining values are based on the values you used during setup.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">influxdb:</span>
  <span class="hljs-attr">host:</span> <span class="hljs-number">192.168</span><span class="hljs-number">.8</span><span class="hljs-number">.12</span>
  <span class="hljs-attr">port:</span> <span class="hljs-number">8086</span>
  <span class="hljs-attr">database:</span> <span class="hljs-string">homeassistant</span>
  <span class="hljs-attr">username:</span> <span class="hljs-string">root</span>
  <span class="hljs-attr">password:</span> <span class="hljs-string">password</span>
  <span class="hljs-attr">max_retries:</span> <span class="hljs-number">3</span>
  <span class="hljs-attr">default_measurement:</span> <span class="hljs-string">state</span>
</code></pre>
<p>Restart your Home Assistant and go to InfluxDB. Click on the Explore tab, and check to see if you have a <strong>database.autogen</strong> file there<em>.</em> Click on it, and if you see some values under Measurements &amp; Tags, you are good to go.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744468647521/3082e165-04d9-4b7d-bfd7-8de0662c11a9.png" alt="A screenshot of InfluxDB Add-on Explore tab" class="image--center mx-auto" width="1712" height="1357" loading="lazy"></p>
<h2 id="heading-how-to-install-and-configure-grafana">How to Install and Configure Grafana</h2>
<p>Next on our agenda is to install and configure Grafana. The goal is to have Grafana query InfluxDB and make dashboards based on the queried data.</p>
<p>Go to the Add-on store, search for Grafana, and install it. Remember to toggle on those important settings, then start the add-on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744470196074/b3d69925-9ccc-45b9-8078-905866222d15.png" alt="A screenshot of Grafana Add-on page" class="image--center mx-auto" width="1715" height="1386" loading="lazy"></p>
<p>Once it has started, click on Grafana on the sidebar. You will arrive at Grafana’s homepage which is where you can create those dashboards.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744470431232/0e4541a5-344f-4f46-bd85-44f4d92ea53c.png" alt="A screenshot of Grafana Add-on homepage" class="image--center mx-auto" width="1703" height="1346" loading="lazy"></p>
<p>But before you do that, you need to connect InfluxDB to Grafana. Navigate to Grafana’s tab &gt;&gt; Connections. You should see an “Add new connection” page. Search for InfluxDB and choose it. Then click on the add new datasource button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744470636092/8dcb8f2b-7fcd-49d3-80d8-abce4f83ea07.png" alt="A screenshot of Grafana Add-on connection settings page" class="image--center mx-auto" width="1707" height="1355" loading="lazy"></p>
<p>Under HTTP, edit the URL and use <strong>http://ha_ip_address:8086</strong> – don’t omit the <code>http://</code> or try to use <code>localhost</code> with it. Scroll down to the InfluxDB Details and fill in the data you used while setting up InfluxDB. Then click on Save &amp; Test. If the config is correct, you should see a green tick and text saying “datasource is working…measurements found.”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744471708830/5b0d0306-8b74-4c02-9163-cc23a7c3425c.png" alt="A screenshot of Grafana Add-on connection configuration for InfluxDB" class="image--center mx-auto" width="1700" height="1337" loading="lazy"></p>
<h2 id="heading-how-to-create-the-grafana-solar-dashboard">How to Create the Grafana Solar Dashboard</h2>
<p>With that, you should have InfluxDB running and connected to Grafana. Let’s get to building beautiful dashboards out of all the data being generated. This part is subjective, so you can feel free to edit and modify the design to your taste. We will be using this dashboard <a target="_blank" href="https://helio.openculture.org.ng/public-dashboards/cf813bfa739044129e125bdd65db7a65?ref=blog.openculture.org.ng">here</a> as the inspiration for our design.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744548823070/811cb6b1-d3f6-4880-b665-8af999d4c703.png" alt="A screenshot of a dashboard we want to recreate" class="image--center mx-auto" width="1918" height="941" loading="lazy"></p>
<p>So now go to your Grafana in Home Assistant, click on the + icon and create a new dashboard.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744544792278/0bbc6140-1335-4597-a972-80a5ddee1744.png" alt="A screenshot of Grafana homepage" class="image--center mx-auto" width="1721" height="1340" loading="lazy"></p>
<p>You should know that a dashboard in Grafana refers to the full space and each thing placed on the dashboard is a panel. Each visualization on the dashboard is a panel.</p>
<p>Let’s create a new panel. Pick InfluxDB as the data source, and at the <strong>FROM</strong> row, pick W which is the unit we want to create a visualization from. <strong>WHERE</strong> is entity_id::tag, as that is the way to sort the values by Home Assistant sensor entity name. Then pick the entity id of your panel – mine is <strong>growatt_pv1_charge_power.</strong> You can change the panel title, change the visualization to stat, and add the watt as the unit and the base colour to yellow.</p>
<p>The raw query looks like this:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> mean(<span class="hljs-string">"value"</span>) <span class="hljs-keyword">FROM</span> <span class="hljs-string">"W"</span> <span class="hljs-keyword">WHERE</span> (<span class="hljs-string">"entity_id"</span>::tag = <span class="hljs-string">'growatt_pv1_charge_power'</span>) <span class="hljs-keyword">AND</span> $timeFilter <span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> <span class="hljs-built_in">time</span>($__interval) fill(<span class="hljs-literal">null</span>)
</code></pre>
<p>The Grafana edit page looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744550024020/bb50d494-c6bc-45f2-8ff0-17173e7255bc.png" alt="A screenshot of Grafana edit panel view" class="image--center mx-auto" width="1710" height="1258" loading="lazy"></p>
<p>At this point, you should be able to recreate the remaining parts of the dashboard. But I manually did all that, so you don’t have to go through it all yourself if you don’t want to.</p>
<p><a target="_blank" href="https://github.com/LifeofDan-EL/Grafana-Solar-Dashboard">Here</a> is the link to a GitHub repo that has the JSON file of this dashboard. When you go to create a dashboard, you will see an option to import from a JSON file. You can choose to copy and paste or upload the file, whichever works for you.</p>
<p>After importing, you only need to edit each panel through the GUI to use your own entity ID tag in Home Assistant and also the UID of your InfluxDB database.</p>
<p>Here is a picture of my finished result:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744559385614/57b58bfe-7fc2-4fa7-a0d2-19485558899a.png" alt="A screenshot of the finished product of the dashboard I built" class="image--center mx-auto" width="3436" height="1357" loading="lazy"></p>
<h2 id="heading-how-to-create-a-new-admin-user-and-delete-the-default-admin-user">How to Create a New Admin User and Delete the Default Admin User</h2>
<p>By default, the Grafana Add-on in Home Assistant uses an auth proxy and creates a default user (<code>admin</code>) with a password (<code>hassio</code>) that's synced with your HA login session. This prevents password or user changes through the UI.</p>
<p>For context, an auth proxy, or authentication proxy, acts as an intermediary between a client and a target resource, handling authentication and authorization on behalf of the client</p>
<p>As a security step, we need to create a new user for the Grafana Add-on and edit their permission to have admin privileges, then delete the default admin user. This is because you can’t change the default admin user password on the Add-on.</p>
<p>Go to Grafana’s menu &gt; Administration&gt; Users and access &gt; Users. Then create a new user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744571233206/daf2c674-4501-4774-89d9-76992227b531.png" alt="A screenshot of Grafana users setting page" class="image--center mx-auto" width="1721" height="1332" loading="lazy"></p>
<p>Next, give it admin privileges. Edit Grafana Admin to be yes and make sure the organization role is set to admin, then save.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744749794592/21e85eab-99ca-4c7d-9d18-19e9f31ea1da.png" alt="A screenshot of Grafana user setting" class="image--center mx-auto" width="1715" height="1387" loading="lazy"></p>
<p>Go back to the Add-on Configuration tab. Scroll to the Network setting and add a port to expose the Add-on. I will be using port 3000. Save and restart the Add-on. If you have SSL turned on and it isn’t configured, the add-on won’t start. You can disable it as we will have Cloudflare handle that.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744750541094/326aa725-7b81-4407-82ef-e6589a153b9c.png" alt="A screenshot of Grafana Add-on Configuration tab" class="image--center mx-auto" width="1712" height="1388" loading="lazy"></p>
<p>To confirm that the port has been exposed properly, go to <code>http://ha_ip:3000/</code> and confirm you see this Grafana login screen. Make sure it is http and not https.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744563139292/e17d2691-3b77-4faf-997d-95a0b3141066.png" alt="A screenshot of Grafana homepage accessed from outside Home Assistant url" class="image--center mx-auto" width="1698" height="1382" loading="lazy"></p>
<p>Log in as the new user you created. Then go to your list of users and delete the default admin user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1744750661705/1d98e960-e325-4a5c-9746-64ff1819a573.png" alt="A screenshot of edit to the default admin user" class="image--center mx-auto" width="1718" height="1343" loading="lazy"></p>
<p>After that, go back to the Grafana Add-on Configuration tab. Click on the 3 dots on the Options row and choose Edit in YAML. Then add this line below to your configuration file and save.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">grafana_ingress_user:</span> <span class="hljs-string">usernameofnewuser</span>
</code></pre>
<h2 id="heading-how-to-enable-remote-access-to-the-solar-dashboard">How to Enable Remote Access to the Solar Dashboard</h2>
<p>At this point, we have the solar dashboard all ready and we can access it in Home Assistant while inside our home network. But we don’t want it only that way. We want anyone to be able to visit the link without having access to our home network.</p>
<p>I will be implementing this part with the aid of a Home Assistant Cloudflared Add-on that leverages Cloudflare Tunnel. Here is the <a target="_blank" href="https://github.com/brenner-tobias/addon-cloudflared">Github repository</a> – the installation is simple and stress-free.</p>
<p>After going through the setup and having remote access to your Home Assistant network (remember to have 2FA turned on), go to the Cloudflared Add-on configuration tab and edit the Additional Hosts part.</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">subdomain_you_want.your_domain.xyz</span>
  <span class="hljs-attr">service:</span> <span class="hljs-string">http://ha_ip:3000</span>
  <span class="hljs-attr">disableChunkedEncoding:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>Save and restart the Add-on and check the logs. You should see it creating a DNS entry for the hostname you added.</p>
<p>As another security step, go to your Grafana Add-on Configuration tab. Add these values to the environment variables.</p>
<pre><code class="lang-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">GF_AUTH_ANONYMOUS_ENABLED</span>
  <span class="hljs-attr">value:</span> <span class="hljs-string">"true"</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">GF_AUTH_ANONYMOUS_ORG_ROLE</span>
  <span class="hljs-attr">value:</span> <span class="hljs-string">"Viewer"</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">GF_AUTH_DISABLE_LOGIN_FORM</span>
  <span class="hljs-attr">value:</span> <span class="hljs-string">"true"</span>
</code></pre>
<ul>
<li><p><code>GF_AUTH_ANONYMOUS_ENABLED</code>: Anyone who visits Grafana without logging in will still be allowed in.</p>
</li>
<li><p><code>GF_AUTH_ANONYMOUS_ORG_ROLE</code>: This sets the default permission for anonymous users. In this case, anonymous users will have the viewer role.</p>
</li>
<li><p><code>GF_AUTH_DISABLE_LOGIN_FORM</code>: Disables the login form on the Grafana login page. Make sure you are already logged in on the remote hostname. But you can always edit this on the Add-on Configuration tab if you get locked out.</p>
</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Finally, go to the Remote hostname for your Grafana and you should see the Grafana home page. Then go to your dashboards and click on the solar dashboard created. Share it and choose publicly. Now you can share that link (the URL on that page and not the actual copied URL from the share button) with anyone and they can get to see your beautiful dashboard.</p>
<p>This method serves as an all-in-one way of having everything done, through your Home Assistant machine. I hope you had fun tinkering, see you next time.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Home VPN Using Tailscale on a Raspberry Pi ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you’ll learn how to set up a VPN which you can host on a Raspberry Pi. I am a fan of Raspberry Pis because these small form factor computers are a favourite tool for tinkerers, like me. This VPN will allow you to access your home net... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/set-up-a-home-vpn-using-tailscale-on-a-raspberry-pi/</link>
                <guid isPermaLink="false">67e6c11d423cd4f90a6350ab</guid>
                
                    <category>
                        <![CDATA[ iot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Raspberry Pi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vpn ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Homelab ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Anomfueme ]]>
                </dc:creator>
                <pubDate>Fri, 28 Mar 2025 15:32:45 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743175949441/1a8c4705-556c-4a1f-899a-9ac8e968fdc3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you’ll learn how to set up a VPN which you can host on a Raspberry Pi. I am a fan of Raspberry Pis because these small form factor computers are a favourite tool for tinkerers, like me.</p>
<p>This VPN will allow you to access your home network from anywhere as if you’re still at home. So why is this useful, you might ask? Well, it allows you to use your home network IP, no matter where you are, which is a good for privacy.</p>
<p>In this article, we’ll use <a target="_blank" href="https://github.com/tailscale/tailscale">Tailscale</a>, an open-source mesh VPN (Virtual Private Network) service that streamlines connecting devices and services securely across different networks. It enables encrypted point-to-point connections using the open-source <a target="_blank" href="https://www.wireguard.com/">WireGuard</a> protocol. This means that only devices on your private network can communicate with each other.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-raspberry-pi-os-lite-32-bit">Install Raspberry Pi OS Lite (32-bit)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-boot-the-raspberry-pi">Boot The Raspberry Pi</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-ssh-into-the-raspberry-pi-and-login">SSH Into The Raspberry Pi and Login</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-tailscale-on-raspberry-pi">Install Tailscale on Raspberry Pi</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-expiry">Key Expiry</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-configuring-the-raspberry-pi-as-an-exit-node">Configuring the Raspberry Pi as an Exit Node</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li><p>Raspberry Pi (I am working with a Raspberry Pi 5)</p>
</li>
<li><p><a target="_blank" href="https://www.raspberrypi.com/software/">Raspberry Pi Imager</a></p>
</li>
<li><p>A Micro SD Card (8GB is enough)</p>
</li>
<li><p>A Micro SD Card reader for your computer.</p>
</li>
<li><p>Home Router</p>
</li>
<li><p>A <a target="_blank" href="https://tailscale.com/">Tailscale</a> account</p>
</li>
</ul>
<h2 id="heading-install-raspberry-pi-os-lite-32-bit">Install Raspberry Pi OS Lite (32-bit)</h2>
<p>We’ll start this process by installing the Raspberry Pi OS Lite (32-bit) on the micro SD card we have. We will be making use of the Raspberry Pi Imager software which is available for free <a target="_blank" href="https://www.raspberrypi.com/software/">here</a>.</p>
<p>When you run the imager software, pick the Raspberry Pi Device, which for me is a Raspberry Pi 5.</p>
<p>Then in Operating System, click on Raspberry Pi OS (other), then scroll down to Raspberry Pi OS Lite (32-bit)</p>
<p>Next, select your SD card which you have inserted into the card reader, and the card reader into the computer. Your screen should look similar to what you see below. Click on next.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742929198415/b3cd3476-ed82-4db3-9472-f13df2207ca9.png" alt="A Screenshot of the Raspberry Pi Imager software start menu." class="image--center mx-auto" width="751" height="538" loading="lazy"></p>
<p>After next, you should see a pop-up asking if you would like to apply OS customisation settings.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742929274780/4482dd16-8f42-41ec-b1cd-af288180adcb.png" alt="A screenshot of the Raspberry Pi Imager software customisation prompt menu" class="image--center mx-auto" width="703" height="497" loading="lazy"></p>
<p>Next, click on edit settings. Enable set hostname and write the name you want to give the Pi. For this tutorial, I will be using <code>dapivpn</code><em>.</em> Then enable set username and password. Pick a username and a strong and secure password</p>
<p>You can enable configure wireless LAN if you plan to use Wifi, but if you are team Ethernet cable, you can skip this. I will be using WiFi in this tutorial though.</p>
<p>Now you’ll need to enable set local settings and pick your correct time zone and keyboard layout.</p>
<p>After that, go to the Services tab, then enable SSH and click on “Use password authentication”. Then click save, then yes on the apply customisation screen, and yes again. Remember this will erase all the data on the SD card, so make sure you’re using one without any important files on it.</p>
<p>This is how your Raspberry Pi Imager should look now:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742929363470/0c7663d4-a908-4be1-9865-caa665a2ee95.png" alt="A screenshot of the Raspberry Pi Imager software performing the write operation." class="image--center mx-auto" width="721" height="513" loading="lazy"></p>
<h3 id="heading-boot-the-raspberry-pi">Boot the Raspberry Pi</h3>
<p>After this is done, take the SD card and insert it into your Raspberry Pi. Then plug the power cable into the Raspberry Pi and wait some minutes for it to boot properly. You will know it is ready when the green LED light stays on.</p>
<p>Now you should go to your router and set a static IP to the Raspberry Pi. For mine, I set it to <code>192.168.8.21</code><em>.</em></p>
<h3 id="heading-ssh-into-the-raspberry-pi-and-login">SSH into the Raspberry Pi and Login</h3>
<p>Open up your command line terminal. Type “<code>ssh &lt;pi username&gt;@&lt;raspberry_pi_ip_address&gt;</code>”. For me, this would be:</p>
<pre><code class="lang-bash">ssh danpi@192.168.8.21
</code></pre>
<p>Then type in the password you used. You should see your username and the Pi hostname and this confirms you have logged in successfully to it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743088985613/480325b2-496c-4161-96c6-f150f4020922.png" alt="Command line interface showing a successful SSH process" class="image--center mx-auto" width="747" height="382" loading="lazy"></p>
<p>Type in:</p>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<p>You run this command to make sure everything is up to date locally.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742929744252/6200841f-98bb-4bfa-8c30-38159a963e2b.png" alt="Command line interface showing the update command running" class="image--center mx-auto" width="748" height="226" loading="lazy"></p>
<p>Now reboot your Pi after this by typing:</p>
<pre><code class="lang-bash">sudo reboot
</code></pre>
<h2 id="heading-install-tailscale-on-raspberry-pi">Install Tailscale on Raspberry Pi</h2>
<p>Now you’re going to add Tailscale’s package signing key and repository.</p>
<pre><code class="lang-bash">curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg &gt;/dev/null 
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
</code></pre>
<p>Install Tailscale using these commands:</p>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install tailscale
</code></pre>
<p>Next, you need to connect your Pi to your Tailscale network and authenticate. You can do that with the following command:</p>
<pre><code class="lang-bash">sudo tailscale up
</code></pre>
<p>Your browser should look like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742929786462/4d17cfae-0e87-449f-ac13-413a65f3f338.png" alt="Screenshot of the browser showing the authentication screen" class="image--center mx-auto" width="695" height="262" loading="lazy"></p>
<p>To locate the Tailscale IPv4 address for the Raspberry Pi, run this command:</p>
<pre><code class="lang-bash">tailscale ip -4
</code></pre>
<p>You can also see it on the Tailscale dashboard in your browser.</p>
<p>At this point, you’re done installing Tailsacle and you just need to do some finishing touches.</p>
<h2 id="heading-key-expiry">Key Expiry</h2>
<p>There is something you need to know when it comes to adding a device to Tailsacle. By default, and as a security feature, Tailscale requires devices to re-authenticate after a certain period of time has elapsed, usually 180 days.</p>
<p>If the re-authentication does not occur, keys expire and the connection stops working. It’s up to you to choose what you prefer, as this is a security feature that comes with some inconvenience.</p>
<p>I will be disabling the key expiry on the Raspberry Pi, as I fully trust it. To do this, you need to:</p>
<ul>
<li><p>Open the <a target="_blank" href="https://login.tailscale.com/admin/machines">Machines</a> page of the Tailscale admin console.</p>
</li>
<li><p>Find the Raspberry Pi on the row and select the option menu there.</p>
</li>
<li><p>Click on the Disable Key Expiry option. You should see an Expiry Disable label below the machine name.</p>
</li>
</ul>
<h2 id="heading-how-to-configure-the-raspberry-pi-as-an-exit-node">How to Configure the Raspberry Pi as an Exit Node</h2>
<p>Another thing you’ll need to know about when it comes to Tailscale is what an exit node is. A Tailscale exit node is a designated device in your Tailscale network that routes all of your internet traffic through it. No matter where you are, once you have this device activated as an exit node, when you turn on Tailscale, it routes your internet traffic through the device.</p>
<p>Ideally, you want a device that is powered on 24/7 to serve as your exit node. That’s why we are picking the Raspberry Pi, as it is a low-powered computer.</p>
<p>We are already 90% of the way, as we have Tailscale running on our Pi. Remember to also have Tailscale installed on as many devices on your local network as possible. What’s left is to allow your Pi to act as an exit node, so all your internet traffic or LAN traffic routes through it, giving you access to:</p>
<ul>
<li><p>Local network devices at home</p>
</li>
<li><p>Your home public IP</p>
</li>
<li><p>Internal services like NAS, printers, cameras, and so on</p>
</li>
</ul>
<p>To do this, SSH into your Raspberry Pi and follow these steps:</p>
<ul>
<li><p>Enable IP Forwarding. IP forwarding allows your Raspberry Pi to pass traffic between its network interfaces. Run the commands below line by line:</p>
<pre><code class="lang-bash">  <span class="hljs-built_in">echo</span> <span class="hljs-string">"net.ipv4.ip_forward=1"</span> | sudo tee -a /etc/sysctl.conf

  <span class="hljs-built_in">echo</span> <span class="hljs-string">"net.ipv6.conf.all.forwarding=1"</span> | sudo tee -a /etc/sysctl.conf

  sudo sysctl -p /etc/sysctl.conf
</code></pre>
</li>
<li><p>Advertise the Raspberry Pi as an exit node:</p>
<pre><code class="lang-bash">  sudo tailscale up --advertise-exit-node
</code></pre>
</li>
<li><p>Open the <a target="_blank" href="https://login.tailscale.com/admin/machines">Machines</a> page of the Tailscale admin console.</p>
</li>
<li><p>Find the Raspberry Pi on the row. You should see an Exit Node label on its name.</p>
</li>
<li><p>Click on the options menu there and select Edit Route Settings.</p>
</li>
<li><p>Check the box for Use as an exit node, then save.</p>
</li>
</ul>
<p>Now you should see the option of routing the internet through an exit node when you open up your Tailscale app on mobile or PC or anywhere you have it installed. When you see that option, you will also see the Raspberry Pi as an exit node option. You can also add more devices as an exit node if you want more options.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Using the Tailscale app on other devices, you can now route traffic securely through the Raspberry Pi by selecting it as an exit node. Tailscale also provides clear, <a target="_blank" href="https://tailscale.com/kb/1408/quick-guide-exit-nodes#use-an-exit-node">step-by-step guides</a> tailored to each device type for setting up and using an exit node.</p>
<p>You can now be away from your home internet but still connect to the internet as if you were home. See you next time.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
