Creating a Rogue Wi-Fi Access Point using a Raspberry Pi

Creating a Rogue Wi-Fi Access Point using a Raspberry Pi

Creating a Rogue Wi-Fi Access Point using a Raspberry Pi .Having access to internet anywhere and everywhere became _essential_ in our day to day. In the short span of a couple of years, we went from internet being considered a luxury (specially on the go, i.e. mobile) to a everyday commodity.

WiFi became part of our everyday vocabulary, yet, it’s inner workings are still a mistery to many. According with a survey by Symantec, 87% of U.S. consumers have used the readily available public WiFi to connect to the internet (cafes, airports, hotels, etc). Also, 60% of the consumers think their information is safe when using public internet.

Do you connect to public WiFi ? What precautions to you take? If the WiFi network (public or at home) is password-protected, do you consider it safe?

Getting to know the basics

To connect to a WiFi network, you essentialy need two things: the Network Name (SSID) and a passphrase (if it’s protected — usually with WPA2 encryption).

Why some WiFi networks have such a wide coverage? How can the same Network Name (SSID) be available in a big space such as an airport or a shopping mall? The answer is WiFi Access Points.

Extending a network range is achieved by adding more WiFi Access Points that are connected to the same network and are using the same SSID & Passphrase.

To which WiFi Access Point my device is connected to?

While the “formula” varies a bit from vendor to vendor, the rule of thumb generally is that your device connects to the Access Point with better signal/quality. Of course, plenty of other factors such as frequency, channels and protocol weight in.

In OSX, you can use the Airport or the Wireless Diagnostic utilities to scan for all the WiFi Access Points within your range.

You might have noticed from the screenshots above that, despite some Access Points are serving the same SSID, they each have a unique identifier called BSSID.

Adding a “rogue” Wi-Fi Access Point

Adding a new Wi-Fi Access Point to an existing network is quite straightforward. As you saw from the images above, you simply need to use the same SSID & Passphrase and connect to the same physical network. But, if we think about Wi-Fi public networks (e.g. cafes, airports, hotels, etc) where you are only interested in getting access to Internet, a simple question comes up:

What if….> What if….

Of course, the devices connected to the rogue Access Point will not be able to interact with other devices or resources within the same physical network we are “impersonating”. However, that is completely irrelevant and goes unnoticed if the devices connected are only interested in accessing the internet.

In practice, how easy is to create a rogue Wi-Fi Access Point?

Meet RogueOne: a Raspberry PI Wi-Fi Rogue Access Point

Pre-requisites:

Raspberry with latest Raspbian (Debian Stretch)

2 x USB Wi-Fi dongles

What if….

# Wi-Fi Additional Drivers Install (if needed)
# MrEngman
sudo wget http://www.fars-robotics.net/install-wifi -O /usr/bin/install-wifi
sudo chmod +x /usr/bin/install-wifi
sudo install-wifi

What if….### Getting RogueOne up and running

To create our rogue Wi-Fi access point, we will need to configure three services (hostapd, dhcpcd and dnsmasqd) in addition to the connection as wifi client to the phone Wi-Fi hotspot.

# Install required component packages

sudo apt-get update
sudo apt-get install hostapd dnsmasq bridge-utils iptables -qy
sudo systemctl stop dnsmasq
sudo systemctl stop hostapd
sudo systemctl stop dhcpcd

# WPA Supplicant: Connect to your Phone (Internet)

sudo cat << 'EOF' > /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=FI
network={
 ssid="MyPhoneHotspot"
 psk="randompassword"
}

EOF

The dhcpdcd component will be responsible to dynamically distribute network information (e.g. ip address, net mask, etc) to the clients connecting to our Wi-Fi Access Point.

Please note the section related to the interface **wlan0 **—we configure a static ip and disable wpa_supplicant on this network interface.

sudo cat << 'EOF' > /etc/dhcpcd.conf
hostname
clientid
persistent
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
option ntp_servers
option interface_mtu
require dhcp_server_identifier
slaac private
interface wlan0
 static ip_address=10.3.0.1/24
        nohook wpa_supplicant
denyinterfaces eth0
EOF 
sudo service dhcpcd restart

The dnsmasq component will provide DNS information and advertise the network routes to the clients connecting to our Wi-Fi Access Point.

Please note that this is where we are defining the dhcp range our clients will be using. Obviously, this needs to match the same subnet information we defined in dhcpcd.

sudo cat << 'EOF' > /etc/dnsmasq.conf
interface=wlan0
 dhcp-range=10.3.0.2,10.3.0.50,255.255.255.0,24h
server=8.8.8.8
listen-address=127.0.0.1
listen-address=10.3.0.1
#no-dhcp-interface=
no-hosts
addn-hosts=/etc/spoof.hosts
EOF
sudo touch /etc/spoof.hosts
sudo service dnsmasq restart

The hostapd component will enable the network interface wlan0 to act as a Wi-Fi Access Point. Please note that the network SSID and Passphrase we want to use are also defined in the configuration file. You can adjust this as needed.

What if….

sudo cat << 'EOF' > /etc/hostapd/hostapd.conf
country_code=FI
ieee80211d=1
ieee80211h=1
interface=wlan0
driver=nl80211
# Use the 2.4GHz band
hw_mode=g
# Use channel 6
channel=6
# Enable 802.11n
ieee80211n=1
# Enable WMM
wmm_enabled=1
# Enable 40MHz channels with 20ns guard interval
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
# Use WPA authentication
auth_algs=1
# Require clients to know the network name
ignore_broadcast_ssid=0
# Use WPA2
wpa=2
# Use a pre-shared key
wpa_key_mgmt=WPA-PSK
# Use AES, instead of TKIP
rsn_pairwise=CCMP
ssid=Intercept
wpa_passphrase=oneveryuniquepassword
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
EOF
sudo echo "DAEMON_CONF=\"/etc/hostapd/hostapd.conf\"" >> /etc/default/hostapd
sudo service hostapd restart


To allow the traffic to be forwarded between the two network interfaces (wlan0 and wlan1), we need to enable IP Forwarding and define an iptables rule.

sudo echo “net.ipv4.ip_forward=1” >> /etc/sysctl.conf
sudo iptables -t nat -A  POSTROUTING -o wlan0 -j MASQUERADE
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
# Make it persistent
sudo cat << 'EOF' > /etc/rc.local
#!/bin/sh -e
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
iptables-restore < /etc/iptables.ipv4.nat
exit 0
EOF

You can now reboot your Raspberry Pi and take all the changes into effect. After the reboot and your becomes available, you can verify with iwconfig the status of the two Wi-Fi interfaces. The first device wlan0 should be set to Access Point ESSID: Intercept and the second device wlan1 should be connected to your phone WiFi hotspot.

Go ahead and connect one device (e.g. your tablet) to the Intercept Wi-Fi network.

You should be able to get internet connectivity straight away. Also, via your Raspberry Pi you can verify that the device is indeed connected using the hostapd_cli tool.

By having clients connected to the internet via your Raspberry Pi, you are now able to see the traffic flow using tools such as tcpdump.

With full control over the Raspberry Pi and with Wi-Fi clients connected to it, we have a powerful tool that can be used to different types of Man-in-the-Middle attacks.

Conclusion

I hope you found this article useful and informative. Please share your feedback and thoughts.

Learn more

Raspberry Pi meets Arduino

A Rookie’s Guide to Raspberry Pi

Hardware projects using Raspberry Pi

Home Automation using Raspberry Pi

Physical Computing with Scratch using Raspberry Pi

Using Raspberry-Pi To Solve a Networking Issue

Using Raspberry-Pi To Solve a Networking Issue

Using Raspberry-Pi To Solve a Networking Issue. We have a unique situation where I have multiple devices sitting inside a network with no way to access them remotely since all the devices use the HTTP ports.

Using an AT&T-Uverse modem-router is very simple, but for some strange reason, this particular model does not do port redirection(not to be confused with port forwarding). Normally with port-redirection (like most Dlink routers have), you can easily “redirect” a port in the event of a port-number conflict. For instance, if you have a two printer-servers and both use the same port (example port 10000), you can redirect one of them to, for example, port 10001). 

So, if your modem-router does allow for port-redirection, a Raspberry-Pi can do the redirecting for you!

In my specific situation, I currently have a half-dozen network devices, all using port 80.

The Raspberry-Pi is unbelievably easy to set up. I just used the default operating system Raspbian, a Debian-based OS.

Linux raspberrypi 4.14.71-v7+ #1145 SMP Fri Sep 21 15:38:35 BST 2018 armv7l GNU/Linux

Then, it was a simple matter of setting up a series of iptables commands to do the redirection for me. Here is my bash script that runs at startup:

#! /bin/bash

sudo echo "1" > /proc/sys/net/ipv4/ip_forward   ;

sudo iptables  --flush  ;               ## there is probably a better way....

sudo iptables -I INPUT 1 -i eth0 -p tcp --dport 8080 -j ACCEPT  ;       ## for rasberry pi apache2 server.....

IPTBL=/sbin/iptables    ;
IF_IN=eth0              ;
INSECURE_PORT=80        ;
SECURE_PORT=443         ;

function iptablesCommands       {

        PORT_IN=$1      ;
        IP_OUT=$2       ;
        PORT_OUT=$3     ;

        echo "redirecting $IP_OUT from $PORT_IN to $PORT_OUT."  ;

        $IPTBL -A PREROUTING -t nat -i $IF_IN -p tcp --dport $PORT_IN -j DNAT --to-destination ${IP_OUT}:${PORT_OUT}    ;
        $IPTBL -A FORWARD -p tcp -d $IP_OUT --dport $PORT_OUT -j ACCEPT                                                 ;
        $IPTBL -A POSTROUTING -t nat -j MASQUERADE                                                                      ;
}

iptablesCommands        '10020' '192.168.1.20'  ${SECURE_PORT}  ;       ## main radio #123
iptablesCommands        '10021' '192.168.1.21'  ${SECURE_PORT}  ;       ## unit #118
iptablesCommands        '10025' '192.168.1.25'  ${SECURE_PORT}  ;       ## #143
iptablesCommands        '10029' '192.168.1.29'  ${SECURE_PORT}  ;       ## spare unit

iptablesCommands        '10030' '192.168.1.30'  ${SECURE_PORT}  ;       ## NEW base #123
iptablesCommands        '10031' '192.168.1.31'  ${SECURE_PORT}  ;       ## 143 NEW STATION

This script simply establishes a function, then passes it a series of parameters.

 

To get the script to run at bootup, this line was entered into crontab:

@reboot  ( sleep 15  ;  bash -vx  /home/pi/iptablesSetup.bsh  )   > /home/pi/iptablesSetup.bsh.log 2>&1

Why the need to pause during startup? Good question, and I have no answer. But otherwise, the iptables would all be reset. Perhaps its a timing issue, but I decided not to investigate and further.

Next, I wanted the Apache web server running so I could put all these port references somewhere as a convenient link. The /etc/apache2/ports.conf file had to be modified. The line:

Listen 80

was changed to

Listen 8080

Then it was just a matter of editing /var/www/html/index.html and adding the necessary links.

This Raspberry-Pi unit needs to have its own a static IP:

sudo  ifconfig  eth0  192.168.1.86   netmask  255.255.255.0  up  ;

Finally, all the referenced ports must be entered into the modem-router using the “port-forward”. This was simply a matter of redirecting all incoming traffic from ports 8080, 10020-10050 to the Raspberry-Pi device at 192.168.1.86.

 

Then I selected a domain name through https://namecheap.com, and created a sub-domain, and referenced the modem-router IP number. Note that this IP number is not permanently assigned to me, but my DSL service has not changed it in two years.

Now all the devices are all accessible remotely. Please feel free to leave comments with suggestions and improvements.

Further reading:

Raspberry Pi 4 Kit - Unboxing and Building

Raspberry Pi 4 on the Raspberry Pi 4 - Computerphile

I created a home IoT setup with AWS, Raspberry Pi

Benchmarking the Raspberry Pi 4

Creating a Rogue Wi-Fi Access Point using a Raspberry Pi

Building a Smart Garden With Raspberry Pi 3B+

How To Serve Node.js Applications with Nginx on a Raspberry

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.

How To Serve Node.js Applications with Nginx on a Raspberry

How To Serve Node.js Applications with Nginx on a Raspberry

This is a tutorial of how I made my own server with Nginx to serve Node.js applications using a Raspberry Pi on my local network. I did it to have my own development server in my local network before committing any changes to the production host. We’ll go through all the steps so you can easily make your own too.

Originally published by Guim Gonzalez at dev.to

Prerequisites and specifications

For this tutorial, I suppose you have a Rasberry Pi with the Raspbian OS installed, root access to the board, another computer connected on the same network, and access to your Wifi app.

  • Board model: Raspberry Pi 3 B+
  • Board OS: Raspbian
  • Board CPU: ARMv7l
Install and run Nginx

To install Nginx and start the service on your Raspberry, open the terminal and type the following commands:

sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx

Now your Nginx server is up and running. To check if the server is working properly, we can open a web browser from another computer and search for our Raspberry local IP. If you don’t know whats your Raspberry local IP open a new terminal and type:

hostname -I

In my case, it’s 192.168.0.173. So the address I have to search for will be http://192.168.0.173. Here you can see the default landing page of Nginx.

Congratulations, your Nginx server is working. Now we have to serve Node.js applications instead of static HTMLfiles. How?

Install Node.js and NPM

Obviously, to work with Node.js, we first need to install Node.js packages and NPM (node package manager). We’ll also update NPM to the latest version. To do so, open a new terminal and type:

sudo apt-get install nodejs
sudo apt-get install npm
npm install -g npm

To check if both Node.js and NPM are installed properly, run the following commands:

nodejs -v
npm -v

Now that we have Nginx running and Node.js installed, it’s time to make our first Node app. The app will be a simple “Hello World” to check if Node and Nginx have good communication. Let’s write the app.

Create a Node.js app

In your home directory create a new folder called server. In this folder, we’ll create our Node.js app. Let’s write the index.js file.

const express = require("express");
const app = express();

// The HelloWorld
app.get("/", (req, res) => {
res.send("Hello from Node.js!");
});

const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(App listening on http://localhost:${port});
});

Save this file in the server directory we created before. To make this app work, we need to install the expresspackages. Open a terminal, go to your server folder and use NPM to install them:

cd ~/server
npm init -y
npm install express --save

What we did is to initialize NPM and install the express packages. Now we can run the app with Node.js:

nodejs index.js

If you open a browser in your Raspberry and search for http://localhost:3000 you’ll see this Node “Hello World”.

Nginx Proxy to the app

Our app is now running in port 3000. But what we want is to redirect all the HTTP requests in port 80 (the Nginxserver) to the port 3000 (the Node.js app). We can do this modifying the default configuration file of Nginx.

server {
listen 80 default_server;
listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
            proxy_pass http://localhost:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
    }

}

Copy this configuration, delete all the text in your config file and paste it. To edit your default file type:

sudo nano /etc/nginx/sites-enabled/default

When you’re finished editing type crtl+X to save changes before exit. Don’t forget to restart your Nginx service:

sudo systemctl restart nginx

Now your Nginx is redirecting your HTTP requests to your localhost app. If we visit http://192.168.0.173 again (the address where Nginx is listening to) we now have to see the Node “Hello World”.

Configure IP tables

The only problem right now is we can access the app via http://localhost (thanks to Nginx) but still with http://localhost:3000 (the Node.js direct access). We don’t want this port 3000 open to anyone.

Imagine in the future you want to redirect all port 80 connections to port 443 because you transport personal data and you need an SSL certificate. People could still connect to port 3000 an omit this encrypted connection.

To solve this we just need to change two rules in our IP tables. The first one will allow localhost (the Raspberry) to connect to port 3000. The second one will deny access to anyone else. Open the terminal and type this:

iptables -A INPUT -p tcp -s localhost --dport 3000 -j ACCEPT
iptables -A INPUT -p tcp --dport 3000 -j DROP

DHCP IP reservation

Another thing you may want to do is to reserve an IP for your Raspberry. So your device has the same IP address every time it connects to your Wifi.

  • Open your Wifi app visiting: http://192.168.0.1 (This is your routers address)
  • Log in with the user and password printed on the bottom of the router.
  • There is a section called Advanced Networking.
  • Search for the DHCP IP reservations.
  • Click add device and search for your Raspberry.
  • Change the last number of the IP address to your will.
Last words

I hope this tutorial was useful for you. If you had any trouble in any of the steps just leave it in the comments below and I’ll do my best to help you. Thanks!

============================================

Originally published by Guim Gonzalez at dev.to

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter


Learn More

☞ MongoDB, Express, Vue.js 2, Node.js (MEVN) and SocketIO Chat App

☞ Node.js / Javascript performance coding tips to make applications faster

☞ Building MongoDB Dashboard using Node.js

☞ Run your Node.js application on a headless Raspberry Pi

☞ The Complete Node.js Developer Course (2nd Edition)

☞ Learn and Understand NodeJS

☞ Node JS: Advanced Concepts

☞ GraphQL: Learning GraphQL with Node.Js

☞ Angular (Angular 2+) & NodeJS - The MEAN Stack Guide

☞ Beginner Full Stack Web Development: HTML, CSS, React & Node

☞ Node with React: Fullstack Web Development

☞ MERN Stack Front To Back: Full Stack React, Redux & Node.js

Node.js and RaspberryPI : Step by Step Installation Guide

Node.js  and RaspberryPI : Step by Step Installation Guide

In this “RaspberryPI and Node.js” series, we are going to first learn about how to install Node.js in RaspberryPI. We will go through each and every step to help you get Node.js running in RaspberryPI.

Hardware requirement

Full disclosure: Link attached to the products listed above are affiliate links and if you buy from Gearbest, we will earn few bucks as a commission. Support us if you can and thank you in advance.

Downloading RaspberryPI Operating system

We will use Raspbian – official and supported operating system by RaspberryPI. Visit the official website by clicking here and download the Raspbian Jessie with pixel zip and make sure to not download the lite version.

Depending on your internet connection, it may take some time (Not applicable to people work in NASA :P). Go grab a coffee and sit back relax.

Writing RaspberryPI OS to the memory card

Once you complete the download, now you need to write the image file in MicroSD card.

But why?

We need to boot our RaspberryPI using the Raspbian operating system and to do that we need to plug in our MicroSD chip in the RaspberryPI and it will boot the operating system.

You can write the operating system image in MicroSD card using any disk image burning software, however, I recommend using Etcher which is cross platform tool to burn the image file to disk.

Download Etcher for your operating system from here.

Now follow the steps mentioned below to write the disk image in MicroSD card.

  1. Insert MicroSD card in the card reader. Refer diagram below.
  2. Insert card reader in your laptop/desktop.
  3. Open Etcher and select the Raspbian Image you just download, then select your SD card drive and click on Flash button to write the image file in SD card.

It will take some time to write the image in SD card.

Booting up RaspberryPI

Ok! So we have Raspbian OS flashed in SD card, RaspberryPI along with keyboard,mouse, and monitor.

First of all, let’s insert our SD card in RaspberryPI. Turn around the RaspberryPI and on the back side there is small card holder, insert your SD card into the slot, refer image below for reference.

Ok, so we have the SD card in place, let’s connect all of our hardware i.e Keyboard, mouse, and a monitor. Here is the reference image for understanding.

Once everything is connected, plug the power supply USB cable to a power source. I am powering it using my Laptop USB. RaspberryPI will boot and you should see OS booting up in the monitor screen.

Once the boot is complete, you will see a desktop screen similar to what shown below.

Congratulations! RaspberryPI is up. Let’s configure some settings in next section.

Configuring Raspbian OS

By default, RaspberryPI uses the UK based keyboard setting and language is the UK English too. In order to change it according to your locality, open the RaspberryPI configuration.

Click on Set Locale button and select the preffered language.

Change the keyboard setting according to your locality.

Now click on the Wifi icon at the right corner and connect to the Wifi. Alternatively, you can also plug the ethernet cable in the RaspberryPI.

Now let’s install the Raspbian system update before installing Node.js.

Open up terminal (Icon at the main bar) and run the following command.

sudo apt-get update

Once the update is done, we are good to install Node.js in our RaspberryPI.

Installing Node.js in RaspberryPI

Open the terminal and run the following command.

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -

Now run the following command to install Node.js.

sudo apt-get install -y nodejs

Let’s check if Node is installed.

Awesome! We have Node.js installed and ready to use.

Next tutorial

In next tutorial, we are going to learn how to configure RaspberryPI with external camera. Stay tuned.

Conclusion

We learned how to configure, boot and setup RaspberryPI step by step with each detail. We also learned about changing the RaspberryPI setting and updating it with latest updates. We also installed Node.js in our RaspberryPI which we are going to use in coming tutorials in “RaspberryPI and Node.js” series.

Further reading:

Deploying NestJS Apps to Zeit Now

Convert SVG to PNG Using NodeJS & Sharp

Building a Node API with Stateless Authentication

ABC's of JavaScript and Node.js

How to Build a Webstore Using Modern Stack (Nest.js, GraphQL, Apollo) Part 1

You don’t need Babel with Node

How To Install Node.js on Debian 10

Structure Node.js App - Fractal Pattern - 2019

Make CRUD simple with Nodejs, GraphQL, and React

Raspberry Pi 4 on the Raspberry Pi 4 - Computerphile

Raspberry Pi 4 on the Raspberry Pi 4 - Computerphile

A quick tour of the Raspberry Pi 4 edited on the Raspberry Pi 4. Dr Steve Bagley gets out his knife.dll to unbox Sean's purchases! ☞ [I created a home IoT setup with AWS, Raspberry...

A quick tour of the Raspberry Pi 4 edited on the Raspberry Pi 4. Dr Steve Bagley gets out his knife.dll to unbox Sean's purchases!

I created a home IoT setup with AWS, Raspberry Pi

Benchmarking the Raspberry Pi 4

The easy way to set up Docker on a Raspberry Pi – freeCodeCamp.org

Creating a Rogue Wi-Fi Access Point using a Raspberry Pi

Building a Smart Garden With Raspberry Pi 3B+