
<rss version="2.0" 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/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Tue, 14 Apr 2026 18:40:53 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Building a Pet Cam using a Raspberry Pi, Cloudflare Tunnels and Teams]]></title>
            <link>https://blog.cloudflare.com/building-a-pet-cam-using-a-raspberry-pi-cloudflare-tunnels-and-teams/</link>
            <pubDate>Thu, 19 Aug 2021 12:59:03 GMT</pubDate>
            <description><![CDATA[ This was a perfect weekend project: I would set up my own pet cam, connect it to the Internet, and make it available for me to check from anywhere in the world. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>I adopted Ziggy in late 2020. It took me quite a while to get used to his routine and mix it with mine. He consistently jumped on the kitchen counter in search of food, albeit only when no one was around. And I only found out when he tossed the ceramic butter box. It shattered and made a loud bang in the late hours of the night. Thankfully, no one was asleep yet.</p><p>This got me thinking that I should keep an eye on his mischievous behaviour, even when I'm not physically at home. I briefly considered buying a pet cam, but I remembered I had bought a Raspberry Pi a few months before. It was hardly being used, and it had a case (like <a href="https://thepihut.com/collections/raspberry-pi-4-cases/products/pir-camera-case-for-raspberry-pi-4-3">this</a>) allowing a camera module to be added. I hadn’t found a use for the camera module — until now.</p><p>This was a perfect weekend project: I would set up my own pet cam, connect it to the Internet, and make it available for me to check from anywhere in the world. I also wanted to ensure that only I could access it and that it had some easy way to login, possibly using my Google account. The solution? Cloudflare Tunnel and Teams. Cloudflare would help me expose a service running in an internal network using <a href="https://www.cloudflare.com/products/tunnel/">Tunnel</a> while providing a security solution on top of it to keep it secure. <a href="https://www.cloudflare.com/teams/">Teams</a> on the other hand, would help me by adding access control in the form of Google authentication.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5bWBM8Z87zIOnvBG8TYXJ3/54946b52cfe1989747b9400f2c2f2b66/image10.jpg" />
            
            </figure><p>So all I am left to do is configure my Raspberry Pi to be able to run a camera as a web service. That weekend, I started researching for it and made a list of things I needed:</p><ul><li><p>A Raspberry Pi with a compatible camera module. I used a <a href="https://www.raspberrypi.org/products/raspberry-pi-4-model-b/">Raspberry Pi 4 model B</a> with <a href="https://www.raspberrypi.org/products/camera-module-v2/">camera module v2</a>.</p></li><li><p>Linux knowledge.</p></li><li><p>A domain name I could make changes to.</p></li><li><p>Understanding of how DNS works.</p></li><li><p>A Cloudflare account with Cloudflare for Teams+Tunnel access.</p></li><li><p>Internet connection.</p></li></ul><p>In this blog post, I’ll walk you through the process I followed to set everything up for the pet cam. To keep things simple and succinct, I will not cover how to set up your Raspberry Pi, but you should make sure it has Internet access and that you can run shell commands on it, either via <a href="https://www.cloudflare.com/learning/access-management/what-is-ssh/">SSH</a> or using a <a href="https://www.realvnc.com/en/">VNC connection</a>.</p>
    <div>
      <h3>Setup</h3>
      <a href="#setup">
        
      </a>
    </div>
    <p>The first thing we need to do is connect the camera module to the Raspberry Pi. For more detailed instructions, follow the <a href="https://projects.raspberrypi.org/en/projects/getting-started-with-picamera/1">official guide</a>, steps 1 to 3.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4nMbgxZI3HylSD6wKx5ImA/cef37fd42e0ea3f4338658d08f45f168/image2.jpg" />
            
            </figure><p>After setting up the camera and testing that it works, we need to set it up as a camera with a web server. This is so we can access it at a URL such as <a href="https://192.168.0.2:8080">https://192.168.0.2:8080</a> within the local network, to which the Raspberry Pi is also connected. To do that, we will use <a href="https://motion-project.github.io/">Motion</a>, a program for setting up the camera module v2 as a web server.</p><p>To install Motion, input these commands:</p>
            <pre><code>$ sudo apt-get update &amp;&amp; sudo apt-get upgrade
$ sudo apt install autoconf automake build-essential pkgconf libtool git libzip-dev libjpeg-dev gettext libmicrohttpd-dev libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libavdevice-dev default-libmysqlclient-dev libpq-dev libsqlite3-dev libwebp-dev
$ sudo wget https://github.com/Motion-Project/motion/releases/download/release-4.3.1/pi_buster_motion_4.3.1-1_armhf.deb
$ sudo dpkg -i pi_buster_motion_4.3.1-1_armhf.deb</code></pre>
            <p>The above commands will update the local packages with new versions from the repositories and then install that version of Motion from Motion’s GitHub project.</p><p>Next, we need to configure Motion using:</p>
            <pre><code>$ sudo vim /etc/motion/motion.conf
# Find the following lines and update them to following:
# daemon on
# stream_localhost off
# save and exit</code></pre>
            <p>After that, we need to set Motion up as a daemon, so it runs whenever the system is restarted:</p>
            <pre><code>$ sudo vim /etc/default/motion
# and change the following line 
# start_motion_daemon=yes
# save and exit and run the next command
$ sudo service motion start</code></pre>
            <p>Great. Now that we have Motion set up, we can see the live feed from our camera in a browser on Raspberry Pi module at the default URL: <a href="http://0.0.0.0:8081"><b>http://localhost:8081</b></a> (the port can be changed in the config edit step above). Alternatively, we can open it on another machine within the same network by replacing 0.0.0.0 with the IP of the Raspberry Pi in the network.</p><p>For now, the camera web server is available only within our local network. However, I wanted to keep an eye on Ziggy no matter where I am, as long as I have Internet access and a browser. This is perfect for <a href="https://www.cloudflare.com/products/tunnel/">Cloudflare Tunnel</a>. An alternative would be to open a port in the firewall on the router in my home network, but I hate that idea of having to mess with the router configuration. I am not really an expert at that, and if I leave a backdoor open to my internal network, it can get scary quickly!</p><p>The Cloudflare Tunnel documentation takes us through <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation">its installation</a>. The only issue is that the architecture of the Raspberry Pi is based on armv7l (32-bit) and there is no package for it in the remote repositories_._ We could build cloudflared from source if we wanted as it’s an <a href="https://github.com/cloudflare/cloudflared">open source project</a>, but an easier route is to <code>wget</code> it.</p>
            <pre><code>$ wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
# a quick check of version shall confirm if it installed correctly
$ cloudflared -v 
cloudflared version 2021.5.10 (built 2021-05-26-1355 UTC)</code></pre>
            <p>Let’s set up our Tunnel now:</p>
            <pre><code>$ cloudflared tunnel create camera
Tunnel credentials written to /home/pi/.cloudflared/5f8182ba-906c-4910-98c3-7d042bda0594.json. cloudflared chose this file based on where your origin certificate was found. Keep this file secret. To revoke these credentials, delete the tunnel.

Created tunnel camera with id 5f8182ba-906c-4910-98c3-7d042bda0594</code></pre>
            <p>Now we need to configure the Tunnel to forward the traffic to the Motion webcam server:</p>
            <pre><code>$ vim /home/pi/.cloudflared/config.yaml 
# And add the following.
tunnel: 5f8182ba-906c-4910-98c3-7d042bda0594
credentials-file: /home/pi/.cloudflared/5f8182ba-906c-4910-98c3-7d042bda0594.json 

ingress:
  - hostname: camera.imohak.com
    service: http://0.0.0.0:9095
  - service: http_status:404</code></pre>
            <p>The Tunnel uuid should be the one created with the command above and so should the path of the credential file. The ingress should have the domain we want to use. In my case I have set up camera.imohak.com as my domain and 404 as the fallback rule.</p><p>Next, we need to route the DNS to this Tunnel:</p>
            <pre><code>$ cloudflared tunnel route dns 5f8182ba-906c-4910-98c3-7d042bda0594 camera.imohak.com</code></pre>
            <p>This adds a DNS CNAME record, which can be verified from the Cloudflare dashboard as shown here:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/72ToAYL4KvcUUsN9mLC4bY/54dcf24add84b971a02085ecb3b1e708/image9.png" />
            
            </figure><p>Let’s test the Tunnel!</p>
            <pre><code>$ cloudflared tunnel run camera
2021-06-15T21:44:41Z INF Starting tunnel tunnelID=5f8182ba-906c-4910-98c3-7d042bda0594
2021-06-15T21:44:41Z INF Version 2021.5.10
2021-06-15T21:44:41Z INF GOOS: linux, GOVersion: go1.16.3, GoArch: arm
2021-06-15T21:44:41Z INF Settings: map[cred-file:/home/pi/.cloudflared/5f8182ba-906c-4910-98c3-7d042bda0594.json credentials-file:/home/pi/.cloudflared/5f8182ba-906c-4910-98c3-7d042bda0594.json]
2021-06-15T21:44:41Z INF cloudflared will not automatically update when run from the shell. To enable auto-updates, run cloudflared as a service: https://developers.cloudflare.com/argo-tunnel/reference/service/
2021-06-15T21:44:41Z INF Generated Connector ID: 7e38566e-0d33-426d-b64d-326d0592486a
2021-06-15T21:44:41Z INF Initial protocol http2
2021-06-15T21:44:41Z INF Starting metrics server on 127.0.0.1:43327/metrics
2021-06-15T21:44:42Z INF Connection 6e7e0168-22a4-4804-968d-0674e4c3b4b1 registered connIndex=0 location=DUB
2021-06-15T21:44:43Z INF Connection fc83017d-46f9-4cee-8fc6-e4ee75c973f5 registered connIndex=1 location=LHR
2021-06-15T21:44:44Z INF Connection 62d28eee-3a1e-46ef-a4ba-050ae6e80aba registered connIndex=2 location=DUB
2021-06-15T21:44:44Z INF Connection 564164b1-7d8b-4c83-a920-79b279659491 registered connIndex=3 location=LHR</code></pre>
            <p>Next, we go to the browser and open the URL camera.imohak.com.</p><p><b>Voilà.</b> Or, not quite yet.</p>
    <div>
      <h3>Locking it Down</h3>
      <a href="#locking-it-down">
        
      </a>
    </div>
    <p>We still haven’t put any requirement for authentication on top of the server. Right now, anyone who knows about the domain can just open it and look at what is happening inside my house. Frightening, right? Thankfully we have two options now:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6ZyzqSJev8PbTkyn3qFn8n/d37bc2f7ced529309f7f173485256d05/image7-1.png" />
            
            </figure><ol><li><p><b>Use </b><a href="https://motion-project.github.io/motion_config.html#webcontrol_authentication"><b>Motion’s inbuilt authentication mechanisms</b></a>. However, we shall not choose this option as it’s just another username/password to remember which one can easily forget and who knows if in the future, there is a vulnerability found in the way motion authenticates and my credentials are leaked? We are looking for an SSO using Google which is easy and quick to use and gives us a secure login based on Google credentials.</p></li><li><p><b>Use Cloudflare Access</b>. Access gives us the ability to create policies based on IP addresses and email addresses, and it lets us integrate different <a href="https://developers.cloudflare.com/cloudflare-one/identity">types of authentication methods</a>, such as OTP or <a href="https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/google">Google</a>. In our case, we require authentication through Google.</p></li></ol><p>To take advantage of this Cloudflare Access functionality, the first step is to set up Cloudflare for Teams. Visit <a href="https://dash.teams.cloudflare.com/">https://dash.teams.cloudflare.com/</a>, follow the <a href="https://developers.cloudflare.com/cloudflare-one/setup">setup guide</a> and choose a team name (imohak in my case).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4Ckc0vrJf3mhwd00R4EPuO/43a6df1837a7eaf0fffd2128e8b467f1/image6-1.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ECuaRhkiYYhB0PAn5wb66/495aced4d3bd416324e365018e0da159/image13.png" />
            
            </figure><p>After this, we have two things left to do: add a login method and add an application. Let’s cover how we add a login method first. Navigate to <b>Configuration</b> &gt; <b>Authentication</b> and click on <b>+Add</b>, under the Login tab. The Dashboard will show us a list of identity providers to choose from. Select <b>Google</b> — follow <a href="https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/google">this guide</a> for a walkthrough of how to set up a Google Cloud application, get a ClientID and Client Secret, and use them to configure the identity provider in Teams.</p><p>After adding a login method and testing it, we should see a confirmation page like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4P79mOvcSRa4tG1MQZlV4b/aa025e7c0fcc069fbcba15750602f4c7/image4-2.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1mrPcowDoLHrYOgO0m5TJZ/56caf36503399da9978180448a6393ec/image11.png" />
            
            </figure><p>The last thing we need to do is to add the pet-cam subdomain as an application protected behind Teams. This enables us to enforce the Google authentication requirement we have configured before. To do that, navigate to <b>Access</b> &gt; <b>Applications</b>, click on <b>Add an application</b>, and select <b>Self-hosted.</b></p><p>On the next page, we specify a name, session duration and also the URL at which the application should be accessible. We add the subdomain <b>camera.imohak.com</b> and also name the app ‘camera’ to keep it simple.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Fw04ynQQofuRrzAEDtNrf/9c9f06d76be3fff0dab3a377b6f1b5bf/image5-6.png" />
            
            </figure><p>Next, we select Google as an identity provider for this application. Given that we are not choosing multiple authentication methods, I can also enable Instant Auth — this means we don’t need to select Google when we open the URL.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4afTGRdT9HqB27ijtHV1sz/899a61e1508a2b83cfa8542c6ebe5754/image3-7.png" />
            
            </figure><p>Now we add policies to the application. Here, we add an email check so that after the Google authentication, a check is made to ensure the specified email address is the only one who is able to access the URL. If needed, we can choose to configure other, more <a href="https://developers.cloudflare.com/cloudflare-one/policies/zero-trust">complex rules</a>. At this point, we click on <b>Next</b> and finish the setup.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1geMYdeb3TxwfOdNX2EbXc/ea5c14428ed5cdcdc83ec87dfa246c2c/image12.png" />
            
            </figure>
    <div>
      <h3>The Result</h3>
      <a href="#the-result">
        
      </a>
    </div>
    <p>The setup is now complete. Time to test everything! After opening the browser and entering my URL, <b>voilà.</b> Now, when I visit this URL, I see a Google authentication page and, after logging in, Ziggy eating his dinner.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/22S1tv39WLxSU92UNgnaPW/a54c9c1de414af27c0f68d9afaba55b2/image8.png" />
            
            </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Tunnel]]></category>
            <category><![CDATA[Cloudflare Zero Trust]]></category>
            <category><![CDATA[Raspberry Pi]]></category>
            <category><![CDATA[Road to Zero Trust]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Developers]]></category>
            <guid isPermaLink="false">5zgPI338Em7XJ667F2OIi8</guid>
            <dc:creator>Mohak Kataria</dc:creator>
        </item>
        <item>
            <title><![CDATA[SSHing to my Raspberry Pi 400 from a browser, with Cloudflare Tunnel and Auditable Terminal]]></title>
            <link>https://blog.cloudflare.com/ssh-raspberry-pi-400-cloudflare-tunnel-auditable-terminal/</link>
            <pubDate>Tue, 27 Apr 2021 13:00:00 GMT</pubDate>
            <description><![CDATA[ This is how I set up a Pi 400 on my home network, used Cloudflare Tunnel to connect it to the Cloudflare network, used Auditable Terminal to connect to the Pi 400 via Cloudflare and the tunnel using nothing more than a browser. ]]></description>
            <content:encoded><![CDATA[ <p>A few weeks ago I received a <a href="https://www.raspberrypi.org/products/raspberry-pi-400/">Raspberry Pi 400</a> as a gift. I didn’t have time to do anything beyond plug it in and verify that it works. It’s great that the Pi 400 comes with everything you need except for a screen: there’s the computer itself, mouse, HDMI cable and power adapter.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1iLQzp8ygoJwH3SyrGKZMA/d525dfc39f36bd14d3c4de6345831ec6/image19-3.png" />
            
            </figure><p>The Pi 400 has been sitting gathering dust when Cloudflare launched <a href="/browser-ssh-terminal-with-auditing/">Auditable Terminal</a> giving me the perfect excuse to get out the Pi 400 and hook it up.</p><p>Auditable Terminal gives you a fully featured <a href="https://www.cloudflare.com/learning/access-management/what-is-ssh/">SSH client</a> in your browser. You authenticate using Cloudflare Access and can log into a computer from anywhere just using the browser and get a terminal. And using Cloudflare Tunnel you can securely connect a computer to Cloudflare without punching holes in a firewall. And you end up with a consistent terminal experience across devices: 256 colours, Unicode support and the same fonts everywhere.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/o8TpljnuZvMufrwXbp0kF/58964a8db07ef957f6491be0f2ff8744/SSHing-to-Raspberry-Pi-400-from-a-browser-2.png" />
            
            </figure><p>This is ideal for my use case: set up the Pi 400 on my home network, use Cloudflare Tunnel to connect it to the Cloudflare network, use Auditable Terminal to connect to the Pi 400 via Cloudflare and the tunnel using nothing more than a browser.</p><p>Here’s what it looks like:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/cGwSFbLHpHDT4NHO2S38C/d065d37de2c52482be8ffb7f12b1afe2/image9-3.png" />
            
            </figure><p>Before getting into the details of how I set that up, it’s worth stopping and appreciating how cool this is. I am logging into the Pi 400 via SSH but inside the browser window just by visiting a URL in a browser and authenticating using Cloudflare for Teams. And since it’s a URL that SSH session can just be a browser bookmark!</p><p>There’s another reason I wanted to do this: I like to use Cloudflare’s own products. I have a number of Cloudflare accounts that I pay for so that I see the true customer experience. I see the emails we send out and what it’s like to navigate our UI for real use. The Pi 400 gave me a chance to experience with Cloudflare Tunnel and Auditable Terminal.</p><p>Also this is really cool.</p><p>So… if you want to do this yourself, follow along as I take you through the steps I went through to hook a brand new Pi 400 up to Cloudflare and access it from anywhere.</p>
    <div>
      <h3>Stage 1: Prepare the Pi</h3>
      <a href="#stage-1-prepare-the-pi">
        
      </a>
    </div>
    <p>I plugged the Pi 400 into my TV via HDMI, to the Internet via Ethernet and booted it. It comes with the OS pre-installed on an SD card so it only took seconds to be at a welcome screen:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3F0OtoSGT7wmqWjrKWRcb/54ddcfadccb377f5e5ccdcd906033e9f/image2-33.png" />
            
            </figure><p>Inevitably with a brand new machine there were a lot of updates to install so I let the machine run through that before logging in for the first time.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/wCAY7rtjgslHDRLgxZq17/b48a45901b92555dc9d3508c89f15f92/image23-1.png" />
            
            </figure><p>The Pi 400 doesn’t come with the SSH server enabled, so it’s necessary to run the raspi-config program from the command line (<code>sudo raspi-config</code>). The SSH server is under option “3 Interface Options”:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3jpPxK6ybyxw9hXyZE3oPy/ae354610118482f8172b055b0af9ec1e/image1-36.png" />
            
            </figure><p>It’s option “P2 SSH” and when turned on will allow SSH access to the machine. By default this will be using SSH with password authentication and so it’s pretty important to change the <a href="https://www.raspberrypi.org/documentation/linux/usage/users.md">default pi/raspberry combination</a> (and to go much further and switch to <a href="https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md">using certificates</a>).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1wNoZtu3lkpdMhsOZjbGSf/149991d77bf2dd57794157128e275f81/image22.png" />
            
            </figure><p>But for the rest of this run through I am going to stick with password authentication in SSH. We’ll see later that Cloudflare has a clever solution to setting up SSH security with certificates.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4hv2ryUuLjXw8PVTiyq4nP/e60164de18c746644dc817b2d663ed70/image4-17.png" />
            
            </figure><p>With SSH access setup and the Pi 400 fully updated, the second step is to set up Cloudflare Tunnel.</p>
    <div>
      <h3>Stage 2: Cloudflare Tunnel</h3>
      <a href="#stage-2-cloudflare-tunnel">
        
      </a>
    </div>
    <p>Even with SSH setup on the Pi 400 it’s only accessible from inside my home network and I want to get access to it from anywhere. I could open a port in my home firewall, but I hate that idea.</p><p>The answer is <a href="/tunnel-for-everyone/">Cloudflare Tunnel</a>. It’s a (free!) small daemon (called <code>cloudflared</code>) that will connect from the Pi 400 to multiple Cloudflare data centers and maintain connections to them. It’ll be authenticated to my Cloudflare account and once setup I’ll be able to use Cloudflare for Teams to connect to it via the web.</p><p>Setting it up is a doddle. I already had a domain name setup on Cloudflare, if I hadn’t I could have set one up quickly. The Cloudflare Tunnel documentation takes you through <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation">installing it</a>.</p><p>The only thing I didn’t know was the architecture of the Pi 400 (32 bit? 64 bit?); so I ran <code>lscpu</code> which tells me that it’s <code>armv7l</code> (which is 32-bit). How did I know that armv7l was 32-bit? I didn’t. I googled it.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2QbeIrW7t5D9NbeFYfrCGN/23e9595bb3477718f432345bcd4e8af8/image10-3.png" />
            
            </figure><p>You can build <code>cloudflared</code> from source if you wish as it’s <a href="https://github.com/cloudflare/cloudflared">an open source project</a>. But I chose to go the speedy route and <code>wget</code> it.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1du0naQQVnv9RfhOUgkoRv/56c4aabd09e3f9a462617414d787ab1a/image25.png" />
            
            </figure><p>With <code>cloudflared</code> installed on the Pi 400 it was time to authenticate it to my account. Authentication is <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/setup">clearly documented</a> and I started by typing <code>cloudflared tunnel login</code>. On a machine with a UI and browser this would have opened the browser ready for me to log into my Cloudflare account and set up <code>cloudflared</code>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3q4FBWTZAnCzzw4IR3cGl/e5db874101a2bb327525c9f320950eca/image30.png" />
            
            </figure><p>Since I was doing all this while SSH’d into the Pi I had to copy and paste the URL to my browser and then choose which of my domains I would use. (I did this before we changed the name from Argo Tunnel to Cloudflare Tunnel… it’s the same thing).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/74FA914g5Q1OFnYkbmRCuu/e57bfb97579b61f670b6e82ecca32c75/image18-1.png" />
            
            </figure><p>Once authorized, the <code>cloudflared</code> command running on the Pi 400 automatically sets up the tunnel. In the dashboard I received confirmation of this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6bgfyl88l05KhttMDo8lFu/a4950872e4c88bca4be74dfc8b58113d/image12-2.png" />
            
            </figure><p>And back on the Pi 400 there was confirmation that <code>cloudflared</code> had been authorized and that a <code>cert.pem</code> file was created.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4A3ptpx0jh88mbLBthatDs/41242e9290cd09e47f5c4566456191b1/image6-9.png" />
            
            </figure><p>Now that <code>cloudflared</code> was authorized it was time to go ahead and set up an actual tunnel that can be used for the Auditable Terminal. I chose the incredibly original name ‘terminal’ for this.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5gvRCPHw35bac1PsnbNDND/37e02200ac1e56032158a19263646d61/image5-15.png" />
            
            </figure><p>At this point the tunnel is set up but not running yet. So the Pi 400 is not yet connected to Cloudflare. I’ll come back to that. But the next step is setting up Cloudflare for Teams so that users can authenticate to the other end of the tunnel and get access.</p>
    <div>
      <h3>Stage 3: Cloudflare for Teams</h3>
      <a href="#stage-3-cloudflare-for-teams">
        
      </a>
    </div>
    <p>I didn’t have Cloudflare for Teams setup so the first step was to visit <a href="https://dash.teams.cloudflare.com/">https://dash.teams.cloudflare.com/</a> and following the <a href="https://developers.cloudflare.com/cloudflare-one/setup">setup guide</a>. I chose the unoriginal team name <code>jgctesting</code> and entered it:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6JLz1E3haHrn0M0mcCwezJ/009f82025e1e78394f0c42ef352386c1/image14-2.png" />
            
            </figure><p>And it’s here that things got complicated. I ended up writing this blog post to give anyone a step-by-step guide to getting Auditable Terminal working, but also so that we can learn from my confusion. (The team has put up a <a href="https://developers.cloudflare.com/cloudflare-one/tutorials/ssh">complete tutorial on this here</a>.)</p><p>If you follow the Cloudflare for Teams documentation <a href="https://developers.cloudflare.com/cloudflare-one/setup">you have three choices</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6jB3b2e8pWeieoufwhrXJx/b9b3f1a9dc9db49b20dc44a92fc110f5/image17-1.png" />
            
            </figure><p>It wasn’t 100% obvious to me that what I needed to do was add an application (as opposed to a location). The answer is… add an application. The process for doing so is documented <a href="https://developers.cloudflare.com/cloudflare-one/applications/configure-apps">here</a>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4kuug4Qk5YIOXjkQz3hxVy/7e98b45bf17e58925e76caa9bdde230c/image8-5.png" />
            
            </figure><p>In particular, I’m going to add a Self-Hosted Application (rather than SaaS) since I’m self-hosting it; it’s an SSH server on a Raspberry Pi 400 hidden behind the sofa after all.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3ji7oP6TOKlYIt1oebB2db/86fb21476259bbf4a66bc8b7539cf27a/image29.png" />
            
            </figure><p>The next step is to give the application a name and specify the URL it will be accessible via. For me that’s “Raspberry Pi 400” (yeah, I’m great with original names) and I’m making it available via pi400.jgc.org.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/TYQZcmonBnnO1lvtEAyjg/aa8285bb8e73762791b60602d95f1d4a/image24-1.png" />
            
            </figure><p>Cloudflare for Teams provides <a href="https://developers.cloudflare.com/cloudflare-one/identity">a lot of different authentication and identity options</a>, but for this demo I am going to use the simplest. When I want to connect to this application (which will be Auditable Terminal ultimately) I’m going to have Cloudflare email me a one-time PIN.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7wzhc881BCW2t4PY4gbzpL/e5eb98aca36e77e4c01c0b4406f97343/image27.png" />
            
            </figure><p>Next up is adding a rule which will let Cloudflare for Teams know who should be allowed access to this application. I am allowing anyone with an @jgc.org email address to get a one-time PIN. Rules can be <a href="https://developers.cloudflare.com/cloudflare-one/policies/zero-trust">much more complex than that</a>!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5FpsRASsImb0v2FuZdqbqj/ae229638cd7cf121f2dc71a5eb82c2d9/image13-2.png" />
            
            </figure><p>And finally I need to enable browser rendering (which will enable the SSH access and Auditable Terminal).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5ItWrD98OwYbP2vaY3TLPT/c8dd2b27c44396443a88f873b568eb30/image21-1.png" />
            
            </figure>
    <div>
      <h3>Stage 4: Connecting it all together</h3>
      <a href="#stage-4-connecting-it-all-together">
        
      </a>
    </div>
    <p>At this stage I had <code>cloudflared</code> setup and authorized on the Pi 400, Cloudflare for Teams setup so that anyone with an @jgc.org email could get a PIN to access Auditable Terminal on pi400.jgc.org (I’ve since reconfigured everything so going to that URL doesn’t do anything today).</p><p>But all these things need connecting together. That means: editing a config file on the Pi 400 and telling Cloudflare to route to the tunnel for pi400.jgc.org.</p><p>I started with the config file which was <code>/home/pi/.cloudflared/config.yml</code>. The first step was to get the tunnel ID.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2f4hfhcaynwnzqjYqMTrPD/64acb352fd2e9c667f29482011cb80e6/image26.png" />
            
            </figure><p>And then edit the config file. Three things needed changing from the defaults: the tunnel (which is just the ID from <code>cloudflared tunnel list</code>), the credentials-file (which is a JSON file in the same location as the config file and with the same name as the tunnel ID) and the hostname (in my case pi400.jgc.org)</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6jONY9bTzvUtqtKNhetxNp/f487684906ba3d897857cf0e720e36bf/image15-1.png" />
            
            </figure><p>With the tunnel installed, authorized and configured I was able to finally run it and make sure that it can connect to Cloudflare. It worked! And created four connections to Cloudflare. Two to Lisbon and two to Amsterdam. Cloudflare Tunnel manages these connections to ensure that my Pi 400 is reachable across the Cloudflare network.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1vocEo7nH49JhiVsp2K6Uz/cd7dea34b918907316a3d417269e3426/image28.png" />
            
            </figure><p>And finally… I just needed to tell <code>cloudflared</code> to route pi400.jgc.org to the tunnel (once again using that tunnel ID).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5pIPdKNnP51fZprVhJZ84i/66f5966d699ad402414cd0fe723e8548/image16-1.png" />
            
            </figure>
    <div>
      <h3>Stage 5: Try it!</h3>
      <a href="#stage-5-try-it">
        
      </a>
    </div>
    <p>And then it was time to try it. I went back to my browser and browsed to pi400.jgc.org and was greeted with a login screen. Since I’d authorized any @jgc.org address I entered an @jgc.org email.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3FbbUNbLA5eXx5FvmwqOk6/72d4d1138c911792651095eaff987c25/image7-7.png" />
            
            </figure><p>The next step was to enter the one-time PIN that was emailed to me.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4AQho8PD6kZizNUZWbgO1U/3f9fdd722c1cfb1002ec794b9dc1e95e/image11-2.png" />
            
            </figure><p>And, since I am using user/password for SSH I was asked for the user name followed by password.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3QqNL3jQEecwuuDBGUrmfM/6d19258e5d3def737f58392808a0d472/image20-2.png" />
            
            </figure><p>And, wow, there I was looking at a command prompt on the Pi 400.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/WxNCKRqVDcJGSejj2fJS6/084a9d8c1ccee47b82600face96a1c20/pi400-login-OG.png" />
            
            </figure><p>Of course, just doing on my laptop wasn’t enough, so I went ahead and logged in the same way on my phone.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1niCupYzcPJoOdv3CNBQ2k/53750664fbba4d4cb277375e9685cb74/image3.jpg" />
            
            </figure><p>The absolute last step was to make sure that <code>cloudflared</code> <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/run-tunnel/run-as-service">runs automatically</a> which was as simple as typing <code>sudo cloudflared --config .cloudflared/config.yml service install</code>.</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>This was pretty fast (especially factoring in my ignorance about all the details of configuring Cloudflare for Teams and Cloudflare Tunnel). Now I can log into that Pi 400 from anywhere in just a browser. So powerful.</p><p>But it’s still using username/password for SSH and that can be fixed with <a href="https://developers.cloudflare.com/cloudflare-one/identity/users/short-lived-certificates">short-lived certificates</a>. And my authentication to access is using one-time PINs; for a real application it would be <a href="https://developers.cloudflare.com/cloudflare-one/identity/idp-integration">better to use SSO</a>.</p> ]]></content:encoded>
            <category><![CDATA[Raspberry Pi]]></category>
            <category><![CDATA[SSH]]></category>
            <category><![CDATA[Zero Trust]]></category>
            <category><![CDATA[Developers]]></category>
            <guid isPermaLink="false">eOVblYVCUnk4qeqeK7TBW</guid>
            <dc:creator>John Graham-Cumming</dc:creator>
        </item>
        <item>
            <title><![CDATA[Deploying Gateway using a Raspberry Pi, DNS over HTTPS and Pi-hole]]></title>
            <link>https://blog.cloudflare.com/deploying-gateway-using-a-raspberry-pi-dns-over-https-and-pi-hole/</link>
            <pubDate>Tue, 21 Apr 2020 11:00:00 GMT</pubDate>
            <description><![CDATA[ Like many, I work remotely and want to show how to deploy Cloudflare Gateway from home. Its DNS filtering protects networks from malware, phishing, ransomware, and other security threats effectively. ]]></description>
            <content:encoded><![CDATA[ <p>Like many who are able, I am working remotely and in this post, I describe some of the ways to deploy <a href="/protect-your-team-with-cloudflare-gateway/">Cloudflare Gateway</a> directly from your home. Gateway’s DNS filtering protects networks from malware, phishing, ransomware, and other security threats. It’s not only for corporate environments - it can be deployed on your browser or laptop to protect your computer or your home WiFi. Below you will learn how to deploy Gateway, including, but not limited to, DNS over HTTPS (DoH) using a <a href="https://www.raspberrypi.org/">Raspberry Pi</a>, <a href="https://pi-hole.net/">Pi-hole</a> and <a href="https://dnscrypt.info/">DNSCrypt</a>.</p><p>We recently launched Cloudflare Gateway and shortly thereafter, offered it for free until at least September to any company in need. Cloudflare's leadership asked the global Solutions Engineering (SE) team, amongst others, to assist with the incoming onboarding calls. As an SE at Cloudflare, our role is to learn new products, such as Gateway, to educate, and to ensure the success of our prospects and customers. We talk to our customers daily, understand the challenges they face and consult on best practices. We were ready to help!</p><p>One way we stay on top of all the services that Cloudflare provides, is by using them ourselves. In this blog, I'll talk about my experience setting up Cloudflare Gateway.</p><p>Gateway sits between your users, device or network and the public Internet. Once you set up Cloudflare Gateway, the service will inspect and manage all Internet-bound DNS queries. In simple terms, you point your recursive DNS to Cloudflare, and we enforce policies you create, such as activating SafeSearch, an automated filter for adult and offensive content that's built into popular search engines like Google, Bing, DuckDuckGo, Yandex and others.</p><p>There are various methods and locations DNS filtering can be enabled, whether it’s on your entire laptop, each of your individual browsers and devices or your entire home network. With DNS filtering front of mind, including DoH, I explored each model. The model you choose ultimately depends on your objective.</p><p>But first, let’s review what DNS and DNS over HTTPS are.</p><p>DNS is the protocol used to resolve hostnames (like <a href="http://www.cloudflare.com">www.cloudflare.com</a>) into IP addresses, so computers can talk to each other. DNS is an unencrypted clear text protocol, meaning that any eavesdropper or machine between the client and DNS server can see the contents of the DNS request. DNS over HTTPS adds security to DNS and encrypt DNS queries using HTTPS (the protocol we use to encrypt the web).</p>
    <div>
      <h3>Let’s get started</h3>
      <a href="#lets-get-started">
        
      </a>
    </div>
    <p>Navigate to <a href="https://dash.teams.cloudflare.com">https://dash.teams.cloudflare.com</a>. If you don’t already have an account, the sign-up process only takes a few minutes.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1n8xAHDWRIAbKWwth0cHvY/19769138e2c833a919718cfcbe63d0f6/1-1.png" />
            
            </figure><p>Configuring a Gateway <b>location</b>, shown below, is the first step.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ady49utoOigMAgS7QzxbI/507e62b3215444ab8f679ad360325d3d/2-1.png" />
            
            </figure><p>Conceptually similar to HTTPS traffic, when our edge receives an HTTPS request, we match the incoming SNI header to the correct domain’s configuration (or for plain text HTTP the Host header). And when our edge receives a DNS query, we need a similar mapping to identify the correct configuration. We attempt to match configurations, in this order:</p><ol><li><p>DNS over HTTPS check and lookup based on unique hostname</p></li><li><p>IPv4 check and lookup based on source IPv4 address</p></li><li><p>Lookup based on IPv6 destination address</p></li></ol><p>Let’s discuss each option.</p>
    <div>
      <h3>DNS over HTTPS</h3>
      <a href="#dns-over-https">
        
      </a>
    </div>
    <p>The first attempt to match DNS requests to a location is pointing your traffic to a unique DNS over HTTPS hostname. After you configure your first location, you are given a unique destination IPv6 address and a unique DoH endpoint as shown below. Take note of the hostname as you will need it shortly. I’ll first discuss deploying Gateway in a browser and then to your entire network.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1HFWdvOuOfVvg1bTwyLjN1/870ccbd2dab4f4f3f4c9af9fabbe08ff/3.png" />
            
            </figure><p>DNS over HTTPS is my favorite method for deploying Gateway and securing DNS queries at the same time. Enabling DoH prevents anyone but the DNS server of your choosing from seeing your <a href="https://www.cloudflare.com/learning/dns/what-is-dns/">DNS queries</a>.</p>
    <div>
      <h3>Enabling DNS over HTTPS in browsers</h3>
      <a href="#enabling-dns-over-https-in-browsers">
        
      </a>
    </div>
    <p>By enabling it in a browser, only queries issued in that browser are affected. It’s available in most browsers and there are quite a few tutorials online to show you how to turn it on.</p><table><tr><td><p><b>Browser</b></p></td><td><p><b>Supports
DoH</b></p></td><td><p><b>Supports Custom
Alternative Providers</b></p></td><td><p><b>Supports
Custom Servers</b></p></td></tr><tr><td><p><b>Chrome</b></p></td><td><p>Yes</p></td><td><p>Yes</p></td><td><p>No</p></td></tr><tr><td><p><b>Safari</b></p></td><td><p>No</p></td><td><p>No</p></td><td><p>No</p></td></tr><tr><td><p><b>Edge</b></p></td><td><p>Yes**</p></td><td><p>Yes**</p></td><td><p>No**</p></td></tr><tr><td><p><b>Firefox</b></p></td><td><p>Yes</p></td><td><p>Yes</p></td><td><p>Yes</p></td></tr><tr><td><p><b>Opera</b></p></td><td><p>Yes*</p></td><td><p>Yes*</p></td><td><p>No*</p></td></tr><tr><td><p><b>Brave</b></p></td><td><p>Yes*</p></td><td><p>Yes*</p></td><td><p>No*</p></td></tr><tr><td><p><b>Vivaldi</b></p></td><td><p>Yes*</p></td><td><p>Yes*</p></td><td><p>No*</p></td></tr></table><p>* Chromium based browser. Same support as Chrome.</p><p>** Most recent version of <a href="https://support.microsoft.com/en-us/help/4501095/download-the-new-microsoft-edge-based-on-chromium">Edge is built on Chromium</a>.</p>
    <div>
      <h3>Chromium based browsers</h3>
      <a href="#chromium-based-browsers">
        
      </a>
    </div>
    <p>Using Chrome as an example on behalf of all the Chromium-based browsers, enabling DNS over HTTPS is straightforward, but as you can see in the table above, there is one issue: Chrome does not currently support custom servers. So while it is great that a user can protect their DNS queries, they cannot choose the provider, including Gateway.</p><p>Here is how to enable DoH in Chromium based browsers:</p><p>Navigate to <code>chrome://flags</code> and toggle the beta flag to enable.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7q6IpMHlqqtv5xDY1VxNsp/2fcea3020dfae12c74f0b4ecae52c464/4.png" />
            
            </figure>
    <div>
      <h3>Firefox</h3>
      <a href="#firefox">
        
      </a>
    </div>
    <p>Firefox is the exception to the rule because they support both DNS over HTTPS and the ability to define a custom server. Mozilla provides detailed instructions about how to <a href="https://support.mozilla.org/en-US/kb/firefox-dns-over-https#w_manually-enabling-and-disabling-dns-over-https">get started</a>.</p><p>Once enabled, navigate to Preferences → General → Network Security and select ‘Settings’. Scroll to the section ‘Enable DNS over HTTPS’, select ‘Custom’ and input your Gateway DoH address, as shown below:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2R4NdeknrFbnlvJs3vdB5B/79a0f48c9be1db182c1595ae19d180b4/5.png" />
            
            </figure><p>Optionally, you can enable Encrypted SNI (ESNI), which is an <a href="https://datatracker.ietf.org/doc/draft-ietf-tls-esni/">IETF draft</a> for encrypting the SNI headers, by toggling the ‘network.security.esni.enabled’ preference in about:config to ‘true’. <a href="/encrypt-that-sni-firefox-edition/">Read more</a> about how Cloudflare is one of the few providers that supports ESNI by default.</p><p>Congratulations, you’ve configured Gateway using DNS over HTTPS! Keep in mind that only queries issued from the configured browser will be secured. Any other device connected to your network such as your mobile devices, gaming platforms, or smart TVs will still use your network's default DNS server, likely assigned by your ISP.</p>
    <div>
      <h3>Configuring Gateway for your entire home or business network</h3>
      <a href="#configuring-gateway-for-your-entire-home-or-business-network">
        
      </a>
    </div>
    <p>Deploying Gateway at the router level allows you to secure every device on your network without needing to configure each one individually.</p><p>Requirements include:</p><ul><li><p>Access to your router's administrative portal</p></li><li><p>A router that supports DHCP forwarding</p></li><li><p>Raspberry Pi with WiFi or Ethernet connectivity</p></li></ul><p>There aren't any consumer routers on the market that natively support DoH custom servers and likely few that natively support DoH at all. A newer router I purchased, the Netgear R7800, does not support either, but it is one of the most popular routers for flashing <a href="https://dd-wrt.com/">dd-wrt</a> or <a href="https://openwrt.org/">open-wrt</a>, which both support DoH. Unfortunately, neither of these popular firm wares support custom servers.</p><p>While it’s rare to find a router that supports DoH out of the box, DoH with custom servers, or has potential to be flashed, it’s common for a router to support DHCP forwarding (dd-wrt and open-wrt both support DHCP forwarding). So, I installed Pi-hole on my Raspberry Pi and used it as my home network’s DNS and DHCP server.</p>
    <div>
      <h3>Getting started with Pi-hole and dnscrypt-proxy</h3>
      <a href="#getting-started-with-pi-hole-and-dnscrypt-proxy">
        
      </a>
    </div>
    <p>If your Raspberry Pi is new and hasn’t been configured yet, follow their <a href="https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up">guide</a> to get started. (Note: by default, <a href="https://www.raspberrypi.org/documentation/remote-access/ssh/">ssh is disabled</a>, so you will need a keyboard and/or mouse to access your box in your terminal.)</p><p>Once your Raspberry Pi has been initialized, assign it a static IP address in the same network as your router. I hard-coded my router's LAN address to <code>192.168.1.2</code></p><p>Using vim:<code>sudo vi /etc/dhcpcd.conf</code></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5gkULaWLndtqTW0qatevRZ/696bacc42a51328383a4481189a17de2/6.png" />
            
            </figure><p>Restart the service.<code>sudo /etc/init.d/dhcpcd restart</code></p><p>Check that your static IP is configured correctly.<code>ip addr show dev eth0</code></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/48cJf7LUT4XhEY4Wu3u6SQ/4871d38848d1e25cfdee12f42d192a35/7.png" />
            
            </figure><p>Now that your Raspberry Pi is configured, we need to install Pi-hole: <a href="https://github.com/pi-hole/pi-hole/#one-step-automated-install">https://github.com/pi-hole/pi-hole/#one-step-automated-install</a></p><p>I chose to use <a href="https://github.com/DNSCrypt/dnscrypt-proxy">dnscrypt-proxy</a> as the local service that Pi-hole will use to forward all DNS queries. You can find the latest version <a href="https://github.com/DNSCrypt/dnscrypt-proxy/releases">here</a>.</p><p>To install dnscrypt-proxy on your pi-hole, follow these steps:</p><p><code>wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.0.39/dnscrypt-proxy-linux_arm-2.0.39.tar.gztar -xf dnscrypt-proxy-linux_arm-2.0.39.tar.gzmv linux-arm dnscrypt-proxycd dnscrypt-proxycp example-dnscrypt-proxy.toml dnscrypt-proxy.toml</code></p><p>Next step is to build a DoH stamp. A <a href="https://dnscrypt.info/stamps/">stamp</a> is simply an encoded DNS address that encodes your DoH server and other options.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/M5UXEL8vex2j6FG7PYrQm/2547e3e8bb7b36bf2fc44c4de3cc2bec/8.png" />
            
            </figure><p>As a reminder, you can find Gateway’s unique DoH address in your location configuration.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/B0BE0VpCyNvLGO9Vr08vL/98dba04b81e54534703e754f9b36af5c/9.png" />
            
            </figure><p>At the very bottom of your <code>dnscrypt-proxy.toml</code> configuration file, uncomment both lines beneath <code>[static]</code>.</p><ul><li><p>Change  <code>[static.'myserver']</code> to <code>[static.'gateway']</code></p></li><li><p>Replace the default stamp with the one generated above</p></li></ul><p>The static section should look similar to this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/PLyDvqCgFY4d0kO0vB2KZ/360809e390de37d4bc7734da088f68fe/10.png" />
            
            </figure><p>Also in <code>dnscrypt-proxy.toml</code> configuration file, update the following settings:<code>server_names = ['gateway']listen_addresses = ['127.0.0.1:5054']fallback_resolvers = ['1.1.1.1:53', '1.0.0.1:53']cache = false</code></p><p>Now we need to install dnscrypt-proxy as a service and configure Pi-hole to point to the <code>listen_addresses</code> defined above.</p><p>Install dnscrypt-proxy as a service:<code>sudo ./dnscrypt-proxy -service install</code></p><p>Start the service:<code>sudo ./dnscrypt-proxy -service start</code></p><p>You can validate the status of the service by running:<code>sudo service dnscrypt-proxy status</code> or <code>netstat -an | grep 5054</code>:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7AmQUt2G4mtp3B9JvOezQJ/f72b23800fffdb532369b72197870588/11.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4l2yNQ6SHjDH0bv6axEjVB/b745f014586f5d50c458d2938e91f722/12.png" />
            
            </figure><p>Also, confirm the upstream is working by querying localhost on port 5054:<code>dig www.cloudflare.com  -p 5054 @127.0.0.1</code></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6nDFFo5ZUf0qdUxW0qhm9H/584464fa46df364153ccebfe72308101/13.png" />
            
            </figure><p>You will see a matching request in the Gateway query log (note the timestamps match):</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4EfgD0BegLWgPRQNo1xQ0E/4fb6700631b3c5459d21d5eea30570db/14.png" />
            
            </figure>
    <div>
      <h4>Configuring DNS and DHCP in the Pi-hole administrative console</h4>
      <a href="#configuring-dns-and-dhcp-in-the-pi-hole-administrative-console">
        
      </a>
    </div>
    <p>Open your browser and navigate to the Pi-hole’s administrative console. In my case, it’s <a href="http://192.168.1.6/admin">http://192.168.1.6/admin</a></p><p>Go to Settings → DNS to modify the upstream DNS provider, which we’ve just configured to be dnscrypt-proxy.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2DTp5rOs6bx8dAWWEXZ8mz/2c988c52b1fc8788d5a3bfb9aaf39b91/Screen-Shot-2020-04-21-at-9.41.30-AM.png" />
            
            </figure><p>Change the upstream server to <code>127.0.0.1#5054</code> and hit save. According to Pi-hole's <a href="https://docs.pi-hole.net/ftldns/dns-resolver/">forward destination determination</a> algorithm, the fastest upstream DNS server is chosen. Therefore, if you want to deploy redundancy, it has to be done in the DNSCrypt configuration.</p><p>Almost done!</p><p>In Settings→DHCP, enable the DHCP server:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/41Av4X5OMI6Y9NSbdcnwEs/3541123fb9ed7c6505cc5356437bdbb3/16.png" />
            
            </figure><p>Hit save.</p><p>At this point, your Pi-hole server is running in isolation, and we need to deploy it to your network. The simplest way to ensure your Pi-hole is being used exclusively by every device is to use your Pi-hole as both a DNS server and a DHCP server. I’ve found that routers behave oddly if you outsource DNS but not DHCP, so I outsource both.</p><p>After I enabled the DHCP server on the Pi-hole, I set the router’s configuration to DHCP forwarding and defined the Pi-hole static address:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2d3YZJ6ZNT4WxfyW0PgOI6/7daed00420fbfe92f043fe4e7e9d6a67/17.png" />
            
            </figure><p>After applying the routers' configuration, I confirmed it was working properly by forgetting the network in my network settings and re-joining. This results in a new IPv4 address (from our new DHCP server) and if all goes well, a new DNS server (the IP of Pi-hole).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/68h97XSNWbUYIJfngnm87K/1058280247a7142e69c8de457ff17b91/18.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6FjiFFcjMBd7NKT8B7Aaj2/d94c58484be9ff3d95aa12c4622c0eca/19.png" />
            
            </figure><p>Done!</p><p>Now that our entire network is using Gateway, we can configure <a href="https://developers.cloudflare.com/gateway/policies/">Gateway Policies</a> to secure our DNS queries!</p>
    <div>
      <h4>IPv4 check and lookup based on source IPv4 address</h4>
      <a href="#ipv4-check-and-lookup-based-on-source-ipv4-address">
        
      </a>
    </div>
    <p>For this method to work properly, Gateway requires that your network has a static IPv4 address. If your IP address does not change, then this is the quickest solution (but still does not prevent third-parties from seeing what domains you are going to). However, if you are configuring Gateway in your home, like I am, and you don’t explicitly pay for this service, then most likely you have a dynamic IP address. These addresses will always change when your router restarts, intentionally or not.</p>
    <div>
      <h4><b>Lookup based on IPv6 destination address</b></h4>
      <a href="#lookup-based-on-ipv6-destination-address">
        
      </a>
    </div>
    <p>Another option for matching requests in Gateway is to configure your DNS server to point to a unique IPv6 address provided to you by Cloudflare. Any DNS query pointed to this address will be matched properly on our edge.</p><p>This might be a good option if you want to use Cloudflare Gateway on your entire laptop by setting your local DNS resolution to this address. However, if your home router or ISP does not support IPv6, DNS resolution won’t work.</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>In this blog post, we've discussed the various ways Gateway can be deployed and how encrypted DNS is one of the next big Internet privacy improvements. Deploying Gateway can be done on a per-device basis, on your router or even with a Raspberry Pi.</p> ]]></content:encoded>
            <category><![CDATA[Cloudflare Gateway]]></category>
            <category><![CDATA[Cloudflare Access]]></category>
            <category><![CDATA[DoH]]></category>
            <category><![CDATA[Raspberry Pi]]></category>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">6LWKuOHb9cirTiAlNJSbaI</guid>
            <dc:creator>Jason Farber</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare Argo Tunnel with Rust+Raspberry Pi]]></title>
            <link>https://blog.cloudflare.com/cloudflare-argo-tunnel-with-rust-and-raspberry-pi/</link>
            <pubDate>Fri, 06 Apr 2018 14:00:00 GMT</pubDate>
            <description><![CDATA[ Serving content from a Rust web server running on a Raspberry Pi from your home to the world, with a Cloudflare Argo Tunnels. ]]></description>
            <content:encoded><![CDATA[ <p>Yesterday Cloudflare launched <a href="https://developers.cloudflare.com/argo-tunnel/">Argo Tunnel</a>. In the words of the product team:</p><blockquote><p>Argo Tunnel exposes applications running on your local web server, on any network with an Internet connection, without adding DNS records or configuring a firewall or router. It just works.</p></blockquote><p>Once I grokked this, the first thing that came to mind was that I could actually use one of my Raspberry Pi's sitting around to serve a website, without:</p><ul><li><p>A flaky DDNS running on my router</p></li><li><p>Exposing my home network to the world</p></li><li><p>A cloud VM</p></li></ul><p>Ooooh... so exciting.</p>
    <div>
      <h3>The Rig</h3>
      <a href="#the-rig">
        
      </a>
    </div>
    <p>I'll assume you already have a Raspberry Pi with Raspbian on it.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/yhfAIyjzM1fchLSHmBBLg/f32e891d40339d5d66139573d9c0e17b/rig.JPG.jpeg" />
            
            </figure><p>Plug the Pi into your router. It should now have an IP address. Look that up in your router’s admin UI:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6nD8bAb7meAZ3X44R4o8YJ/632c6a588761b86e7c7be9f9e87f8c0e/devices.png" />
            
            </figure><p>OK, that's promising. Let's connect to that IP using the default pi/raspberry credentials:</p>
            <pre><code>$ ssh 192.168.8.26 -l pi
pi@192.168.8.26's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Mar 18 23:24:11 2018 from stevens-air-2.lan
pi@raspberrypi:~ $ </code></pre>
            <p>We're in!</p><p><b>Pro tip: quick way to figure it out which type you have is</b></p>
            <pre><code>pi@raspberrypi:~ $ cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}' | sed 's/^1000//'
a22082</code></pre>
            <p>Then look up the value in the <a href="https://elinux.org/RPi_HardwareHistory">Raspbery Pi revision history</a>. I have Raspberry Pi 3 Model B</p>
    <div>
      <h3>Internet connectivity</h3>
      <a href="#internet-connectivity">
        
      </a>
    </div>
    <p>OK, so we have a Pi connected to our router. Let's make 100% sure it can connect to the Internet.</p>
            <pre><code>pi@raspberrypi:~$ $ curl -I https://www.cloudflare.com
HTTP/2 200
date: Tue, 20 Mar 2018 22:54:20 GMT
content-type: text/html; charset=utf-8
set-cookie: __cfduid=dfb9c369ae12fe6eace48ed9b51aedbb01521586460; expires=Wed, 20-Mar-19 22:54:20 GMT; path=/; domain=.cloudflare.com; HttpOnly
x-powered-by: Express
cache-control: no-cache
x-xss-protection: 1; mode=block
strict-transport-security: max-age=15780000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
served-in-seconds: 0.025
set-cookie: __cflb=3128081942; path=/; expires=Wed, 21-Mar-18 21:54:20 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 3febc2914beb7f06-SFO-DOG</code></pre>
            <p>That first line HTTP/2 200 is the OK status code, which is enough to tell us we can connect out to the Internet. Normally this wouldn't be particularly exciting, as it's allowing connections <b>in</b> that causes problems. That's the promise of Argo Tunnels however, it says on the tin we don't need to poke any firewall holes or configure any DNS. Big claim, let's test it.</p>
    <div>
      <h3>Install the Agent</h3>
      <a href="#install-the-agent">
        
      </a>
    </div>
    <p>Go to <a href="https://developers.cloudflare.com/argo-tunnel/downloads/">https://developers.cloudflare.com/argo-tunnel/downloads/</a> to get the url for the ARM build for your Pi. At the time of writing it was <a href="https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz">https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz</a></p>
            <pre><code>$ wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
Resolving bin.equinox.io (bin.equinox.io)... 54.243.137.45, 107.22.233.132, 50.19.252.69, ...
Connecting to bin.equinox.io (bin.equinox.io)|54.243.137.45|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5293773 (5.0M) [application/octet-stream]
Saving to: ‘cloudflared-stable-linux-arm.tgz’
...</code></pre>
            <p>Untar it</p>
            <pre><code>$ mkdir argo-tunnel
$ tar -xvzf cloudflared-stable-linux-arm.tgz -C ./argo-tunnel
cloudflared
$ cd argo-tunnel</code></pre>
            <p>Check you can execute it.</p>
            <pre><code>$ ./cloudflared --version
cloudflared version 2018.3.0 (built 2018-03-02-1820 UTC)</code></pre>
            <p>Looks OK. Now, we're hoping that the agent will magically connect from the Pi out to the nearest Cloudflare POP. We obviously want that to be secure. Furthermore, we're expecting that when a request comes inbound, it magically gets routed through Cloudflare's network and back to my Raspberry Pi.</p><p>Seems unlikely, but let’s have faith. Here is my mental model of what's happening:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2yhnPd0ciTQSUCgu03CHu7/b5360d9194e28944ed230e6cb5e19fc2/Argo-Tunnel-Diagram.png" />
            
            </figure><p>So let's create that secure tunnel. I guess we need some sort of certificate or credentials...</p>
            <pre><code>$ ./cloudflared login</code></pre>
            <p>You'll see output in the command window similar to this:</p>
            <pre><code>A browser window should have opened at the following URL:

https://www.cloudflare.com/a/warp?callback=&lt;some token&gt;

If the browser failed to open, open it yourself and visit the URL above.</code></pre>
            <p>Our headless Pi doesn't have a web browser, so let's copy the url from the console into the browser on our host dev machine.</p><p>This part assumes you already have a domain on Cloudflare If you don't go to the <a href="https://support.cloudflare.com/hc/en-us/articles/201720164">setup guide</a> to get started.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4NdfPejq5R5wFIBaw6fjmx/04998230fa9a9fae7cef05e0f282cc43/authorize-choose-domain.png" />
            
            </figure><p>We're being asked which domain we want this tunnel to sit behind. I've chosen <b>pacman.wiki</b>. Click Authorize.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2e3js21yw4OkiapEadWalz/bbe4e38f7dcffae2b6f3a98395d5ba9b/authorize-confirm.png" />
            
            </figure>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/49TShvgc3EHdZ9O1a8s1Be/2a346df5abf86d07f15e2f8f271a2619/authorize-complete.png" />
            
            </figure><p>You should now see this back on your pi:</p>
            <pre><code>You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/pi/.cloudflared/cert.pem</code></pre>
            <p>Aha! That answers how the tunnel gets secured. The agent has created a certificate and will use that to secure the connection back to Cloudflare. Now let's create the tunnel and serve some content!</p><p><code>$ cloudflared --hostname [hostname] --hello-world</code></p><p><b>hostname</b> is a fully-qualified domain name under the domain you chose to Authorize for Argo Tunnels earlier. I'm going to use <b>tunnel.pacman.wiki</b></p>
            <pre><code>$ ./cloudflared --hostname tunnel.pacman.wiki --hello-world
INFO[0002] Proxying tunnel requests to https://127.0.0.1:46727 
INFO[0000] Starting Hello World server at 127.0.0.1:53030 
INFO[0000] Starting metrics server                       addr="127.0.0.1:53031"
INFO[0005] Connected to LAX                             
INFO[0010] Connected to SFO-DOG                         
INFO[0012] Connected to LAX                             
INFO[0012] Connected to SFO-DOG  </code></pre>
            <p>Huh, interesting. So, we've connected to my nearest POP(s). I'm in the San Francisco Bay Area, so SJC and LAX seems reasonable. What now though? Surely that's not it? If I'm reading this right, I can go to my browser, enter <a href="https://tunnel.pacman.wiki">https://tunnel.pacman.wiki</a> and I'll get a hello world page... surely not.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4HzTsm0DkHPzZSQ527zAYb/1dec3343ed9ec63465c60fb28dbe60ed/success-1.png" />
            
            </figure><p>And back on the Pi</p>
            <pre><code>INFO[0615] GET https://127.0.0.1:62627/ HTTP/1.1 CF-RAY=4067701b598e8184-LAX
INFO[0615] 200 OK  CF-RAY=4067701b598e8184-LAX</code></pre>
            <p>Mind. Blown. So what happened here exactly...</p><ol><li><p>The agent on the Pi created a secure tunnel (a persistent http2 connection) back to the nearest Cloudflare Argo Tunnels server</p></li><li><p>The tunnel was secured with the certificate generated by the agent.</p></li><li><p>A request for <a href="https://tunnel.pacman.wiki">https://tunnel.pacman.wiki</a> went from my browser out through the Internet and was routed to the nearest Cloudflare <a href="https://www.cloudflare.com/learning/cdn/glossary/anycast-network/">datacenter</a></p></li><li><p>Cloudflare received the request, saw the domain was Cloudflare managed and saw a tunnel set up to that hostname</p></li><li><p>The request got routed over that http2 connection back to my Pi</p></li></ol><p>I'm serving traffic over the Internet, from my Pi, with no ports opened on my home router. That is so cool.</p>
    <div>
      <h3>More than hello world</h3>
      <a href="#more-than-hello-world">
        
      </a>
    </div>
    <p>If you're reading this, I've won my battle with the Cloudflare blog editing team about long form vs short form content :p</p><p>Serving hello world is great, but I want to expose a real web server. If you're like me, if you can find any vaguely relevant reason to use Rust, then you use Rust. If you're also like me, you want to try one of these async web servers the cool kids talk about on <a href="https://www.reddit.com/r/rust/">/r/rust</a> like <a href="https://gotham.rs/">gotham</a>. Let's do it.</p><p>First, install rust using <a href="https://www.rustup.rs/">rustup</a>.</p><p><code>$ curl https://sh.rustup.rs -sSf | sh</code></p><p>When prompted, just hit enter</p>
            <pre><code>1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
...
  stable installed - rustc 1.24.1 (d3ae9a9e0 2018-02-27)
...</code></pre>
            <p>OK, Rust is installed. Now clone Gotham and build the hello_world example:</p>
            <pre><code>$ git clone https://github.com/gotham-rs/gotham
$ cd gotham/examples/hello_world
$ cargo build</code></pre>
            <p><b>Pro tip:</b> if cargo is not found, run <code>source $HOME/.cargo/env</code>. It will be automatic in future sessions.</p><p>As cargo does its magic, you can think to yourself about how it's a great package manager, how there really are a lot of dependencies and how OSS really is standing on the shoulders of giants of giants of giants of giants—eventually you'll have the example built.</p>
            <pre><code>...
Compiling gotham_examples_hello_world v0.0.0 (file:///home/pi/argo-tunnel/gotham/examples/hello_world)
    Finished dev [unoptimized + debuginfo] target(s) in 502.83 secs
    
$ cd ../../target/debug
$ ./gotham_examples_hello_world 
Listening for requests at http://127.0.0.1:7878</code></pre>
            <p>We have a rust web server listening on a local port. Let's connect the tunnel to that.</p><p><code>./cloudflared --hostname gotham.pacman.wiki http://127.0.0.1:7878</code></p><p>Type <b>gotham.pacman.wiki</b> into your web browser and you'll see those glorious words, "Hello, world".</p>
    <div>
      <h2>Wait, this post was meant to be <i>more</i> than hello world.</h2>
      <a href="#wait-this-post-was-meant-to-be-more-than-hello-world">
        
      </a>
    </div>
    <p>OK, challenge accepted. Rust being fancy and modern is OK with Unicode. Let's serve some of that.</p>
            <pre><code>$ cd examples/hello_world/src/
$ nano src/main.rs </code></pre>
            <p>Replace the hello world string:</p><p><code>Some((String::from("Hello World!").into_bytes(), mime::TEXT_PLAIN)),</code></p><p>with some Unicode and a content-type hint so the browser know how to render it:</p><p><code>Some((String::from("&lt;html&gt;&lt;head&gt;&lt;meta http-equiv='Content-Type' content='text/html; charset=UTF-8'&gt;&lt;/head&gt;&lt;body&gt;&lt;marquee&gt;Pᗣᗧ•••MᗣN&lt;/marquee&gt;&lt;/body&gt;&lt;/html&gt;").into_bytes(), mime::TEXT_HTML)),</code></p><p>Build and run</p>
            <pre><code>$ cargo build
...
./gotham_examples_hello_world 
Listening for requests at http://127.0.0.1:7878</code></pre>
            <p><code>$ ./cloudflared --hostname gotham.pacman.wiki http://127.0.0.1:7878</code></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2O0v47vQuYvFKKPsCY134y/22c094cfb746e462c6433e6db493794d/pacman-2.gif" />
            
            </figure><p>And now we have some unicode served from our Pi at home over the Internet by a highly asynchronous web server written in a fast, safe, high-level language. Cool.</p>
    <div>
      <h3>Are we done?</h3>
      <a href="#are-we-done">
        
      </a>
    </div>
    <p>We should probably auto start both the agent and the web server on boot so they don't die when we end our ssh session.</p>
            <pre><code>$ sudo ./cloudflared service install
INFO[0000] Failed to copy user configuration. Before running the service, 
ensure that /etc/cloudflared contains two files, cert.pem and config.yml  
error="open cert.pem: no such file or directory"</code></pre>
            <p>Nice error! OK, the product team have helpfully documented what to put in that file <a href="https://developers.cloudflare.com/argo-tunnel/reference/config/">here</a></p>
            <pre><code>$ sudo cp ~/.cloudflared/cert.pem /etc/cloudflared
$ sudo nano /etc/cloudflared/config.yml</code></pre>
            
            <pre><code>#config.yml
hostname: gotham.pacman.wiki
url: http://127.0.0.1:7878</code></pre>
            
    <div>
      <h4>Autostart for the Agent</h4>
      <a href="#autostart-for-the-agent">
        
      </a>
    </div>
    
            <pre><code>$ sudo ./cloudflared service install
INFO[0000] Using Systemd                                
ERRO[0000] systemctl: Created symlink from /etc/systemd/system/multi-user.target.wants/cloudflared.service to /etc/systemd/system/cloudflared.service.
INFO[0000] systemctl daemon-reload       </code></pre>
            
    <div>
      <h4>Autostart for the Web Server</h4>
      <a href="#autostart-for-the-web-server">
        
      </a>
    </div>
    <p>Copy the web server executable somewhere outside the gotham source tree so you can play around with the source code. I copied mine to <code>/home/pi/argo-tunnel/server/bin/</code></p><p><code>nano /etc/rc.local</code></p><p>Add line: <code>/home/pi/argo-tunnel/server/bin/gotham_examples_hello_world &amp;</code> just before <code>exit 0</code></p><p><code>sudo reboot</code></p><p>On restart, ssh back in again and check both the agent and server are running.</p>
            <pre><code>$ sudo ps -aux | grep tunnel
root       501  0.1  0.2  37636  1976 ?        Sl   06:30   0:00 /home/pi/argo-tunnel/server/bin/gotham_examples_hello_world
root       977 15.7  1.4 801292 13972 ?        Ssl  06:30   0:01 /home/pi/argo-tunnel/cloudflared --config /etc/cloudflared/config.yml --origincert /etc/cloudflared/cert.pem --no-autoupdate</code></pre>
            <p>Profit.</p> ]]></content:encoded>
            <category><![CDATA[Rust]]></category>
            <category><![CDATA[Argo Smart Routing]]></category>
            <category><![CDATA[Raspberry Pi]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[Programming]]></category>
            <category><![CDATA[Cloudflare Tunnel]]></category>
            <guid isPermaLink="false">1fVcP30JWQOAu5llzgN6Yk</guid>
            <dc:creator>Steven Pack</dc:creator>
        </item>
        <item>
            <title><![CDATA[Blue Light Special: Ensuring fast global configuration changes]]></title>
            <link>https://blog.cloudflare.com/blue-light-special/</link>
            <pubDate>Fri, 03 Jul 2015 13:41:49 GMT</pubDate>
            <description><![CDATA[ CloudFlare operates a huge global network of servers that proxy our customers' web sites, operate as caches, inspect requests to ensure they are not malicious, deflect DDoS attacks and handle one of the largest authoritative DNS systems in the world.  ]]></description>
            <content:encoded><![CDATA[ <p>CloudFlare operates a huge global network of servers that proxy our customers' web sites, operate as caches, inspect requests to ensure they are not malicious, deflect DDoS attacks and handle one of the largest authoritative DNS systems in the world. And where there's software there's configuration information.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6AtvZb7LpHv8Y5mInr2Zxi/4737a84e28294c03603509b0e77e4e16/rozzers-1.gif" />
            
            </figure><p>CloudFlare is highly customisable. Each customer has a unique configuration consisting of DNS records, all manner of settings (such as minification, image recompression, IP-based blocking, which individual WAF rules to execute) and per-URL rules. And the configuration changes constantly.</p>
    <div>
      <h3>Warp speed configuration</h3>
      <a href="#warp-speed-configuration">
        
      </a>
    </div>
    <p>We offer almost instant configuration changes. If a user adds a DNS record it should be globally resolvable in seconds. If a user enables a CloudFlare WAF rule it should happen very, very fast to protect a site. This presents a challenge because those configuration changes need to be pushed across the globe very quickly.</p><p>We've written in the past about the underlying technology we use: <a href="/kyoto-tycoon-secure-replication/">Kyoto Tycoon</a> and how we secured it from eavesdroppers. We also monitor its performance.</p><p>DNS records are currently changing at a rate of around 40 per second, 24 hours a day. All those changes need to be propagated in seconds.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/67rzza7FcK2ny8M5NtDIbQ/8e380fc00654bc35961203e4efba1bc9/fakeip.jpg" />
            
            </figure><p>So we take propagation times very seriously.</p>
    <div>
      <h3>Keep a close eye on this light of mine</h3>
      <a href="#keep-a-close-eye-on-this-light-of-mine">
        
      </a>
    </div>
    <p>For this we need to keep a close eye on how long it takes a change to reach every one of our data centers. Whilst we have in-depth metrics for our operations team to look at it's sometimes useful (and fun) to have something more visceral.</p><p>We also want developers and operations people to equally be aware of some critical metrics, and developers are spending their time observing the metrics and alerts aimed at operations.</p><p>On some rare occasions, perhaps due to routing problems on the wider Internet, we may find that our ability to push changes at the required velocity becomes impractical. To ensure that we know about this as soon as possible and know when to take action we've built a custom alert system that everyone in the office can see.</p><p>From an external global collection of machines we monitor propagation time for DNS records and trigger an alert if propagation time exceeds a pre-set threshold. The alert comes in the form of a blue rotating 'police light'.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5TuhyXE68uR226VQJyktNp/3236012d272ad17357da7d1cd0082eb3/IMG_6126.JPG.jpeg" />
            
            </figure><p>We had joked about having a "red alert" alarm when we fall behind on propagation and so I turned that joke into reality.</p>
    <div>
      <h3>Hawaii Pi-O</h3>
      <a href="#hawaii-pi-o">
        
      </a>
    </div>
    <p>A Raspberry Pi hidden in an old hard drive case connects to our global monitors and obtains the current propagation time (as measured from outside our network). The Pi is connected (via a transistor acting as a switch) to a cheap <a href="http://www.maplin.co.uk/p/mini-led-police-beacon-n74kf">mini police light</a> that's visible throughout the office.</p><p>PS: All the puns in this post were added by John Graham-Cumming. I disclaim all responsibility.</p> ]]></content:encoded>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[Reliability]]></category>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[WAF]]></category>
            <category><![CDATA[Raspberry Pi]]></category>
            <guid isPermaLink="false">6R5aFlyXmB7MfjTlojhvJJ</guid>
            <dc:creator>Ben Cartwright-Cox</dc:creator>
        </item>
        <item>
            <title><![CDATA[DIY Web Server: Raspberry Pi + CloudFlare]]></title>
            <link>https://blog.cloudflare.com/dyi-web-server-raspberry-pi-cloudflare/</link>
            <pubDate>Tue, 19 Aug 2014 07:00:00 GMT</pubDate>
            <description><![CDATA[ The Raspberry Pi was created with a simple mission in mind: change the way people interact with computers. This inexpensive, credit card-sized machine is encouraging people, especially kids, to start playing with computers, not on them. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Raspberry Pi was created with a simple mission in mind: change the way people interact with computers. This inexpensive, credit card-sized machine is encouraging people, especially kids, to start playing with computers, not on them.</p><p>When the first computers came out, basic programming skills were necessary. This was the age of the Amigas, BBC Micros, the Spectrum ZX, and Commodore 64s. The generation that grew up with these machines gained a fundamental understanding of how computers work.</p><p>Computers today are easy to use and require zero understanding of programming to operate. They’re also expensive, and wrapped in sleek cases. While aesthetically pleasing designs and user friendly interfaces make computers appealing and accessible to everyone, these advances create a barrier to understanding how computers work and what they are capable of doing. This isn’t necessarily a problem, but for those who really understand computers, it seems that our collective sense of the power of computing has been dulled.</p><p>Raspberry Pi marks the beginning of a conscious effort to return to computing fundamentals. Starting at about $25—case not included—it’s purposely designed to remove barriers to tinkering, reprograming, and, ultimately, to understanding how computers work. This return to fundamentals is rejuvenating the curiosity and creative spirit of computer hobbyists around the world.</p><p>The vibrant community of Raspberry Pi enthusiasts have found good use for an ARM processor, a GPU, a few ports, and an operating system (typically Linux-based) loaded onto an SD card. A quick Google search will return ideas for building your own Pi powered robots and helicopters, humidity and temperature sensors, voice activated coffee machines, and sophisticated home security systems—<a href="http://www.bitrebels.com/technology/a-geeky-collection-of-creative-raspberry-pi-cases-15-pics/">homemade cases</a> encouraged.</p>
    <div>
      <h3>Another slice of Pi?</h3>
      <a href="#another-slice-of-pi">
        
      </a>
    </div>
    <p>Ok, maybe you don’t need a Lego wrapped, solar powered Raspberry Pi syncing your Christmas lights to techno music—most of us don’t. But there are a whole host of practical projects for Pi enthusiasts as well. One of our customers, Scott Schweitzer of Solarflare, turned his Pi into a web server.</p><p>It might seem crazy to host a website on an 8GB SD card since a small surge in traffic would knock the site offline. But with CloudFlare handing the load, speeding up the content, and keeping it secure, a Raspberry Pi is all Scott needed to host his sites. He started by testing one of his sites on his Pi-CloudFlare combo, and once he realized it worked, he called up his hosting provider to cancel his subscription. Now his Raspberry Pi sits in his closet using a trickle of energy, and CloudFlare provides the rest of the power.</p><p>Check out Scott’s project <a href="http://www.scottschweitzer.com/raspberrypi/">here</a>.</p><p>Staying true to the Raspberry Pi mission, Scott provided resources for other members of the Pi community to use.</p>
    <div>
      <h3>The Recipe:</h3>
      <a href="#the-recipe">
        
      </a>
    </div>
    <p>Ingredients</p><ul><li><p>1 Raspberry Pi (the Model B + 512 MB is recommended)</p></li><li><p>1 RJ45 Cat45 cable</p></li><li><p>1 micro-USB power supply</p></li><li><p>1 SD card</p></li></ul><p>Directions:</p><ol><li><p>Follow <a href="http://www.instructables.com/id/59-Web-Server-with-Amazon-Class-Performance-Securi/">these directions</a> put together by ScottSchweitzer of Solarflare.</p></li><li><p>Open port 80 on your home router and map it directly to your Raspberry Pi. Click <a href="http://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/">here</a> to learn more.</p></li><li><p>Put <a href="https://www.cloudflare.com/sign-up">CloudFlare</a> in front of your Pi to protect it from vulnerabilities, and make your site fast and secure.</p></li></ol><p>That's it! This is the simple way of doing it, but Scott took a more roundabout path. He originally set up his Pi as a security penetration test tool using Raspberry Pwn Release 0.2 which is Debian 7 based. You can see that build <a href="https://github.com/pwnieexpress/raspberry_pwn">here</a>. Scott then later added Apache2, but since he didn’t need PHP or MySQL he left those off.</p><p><b>Note:</b> If you prefer Nginx, see <a href="http://elinux.org/RPi_Nginx_Webserver">these instructions</a> for installing it on your Pi.</p><p><b>By the way</b>, if you like hacking on Nginx running on ARM CPU’s <a href="https://www.cloudflare.com/join-our-team">CloudFlare is hiring</a>.</p><p>CloudFlare’s mission is to make the powerful tools used by internet giants accessible to everyone. Scott Schweitzer’s Raspberry Pi web server project is a perfect example.</p><p>Thanks for sharing your story Scott!</p> ]]></content:encoded>
            <category><![CDATA[Raspberry Pi]]></category>
            <category><![CDATA[Programming]]></category>
            <guid isPermaLink="false">6aEN2D6pi2ZzSzR1D6QQ8h</guid>
            <dc:creator>Andrew A. Schafer</dc:creator>
        </item>
    </channel>
</rss>