This project documents the setup and configuration of a personal Raspberry Pi used as a foundational home lab server. The primary objective is to gain practical, hands-on experience with fundamental DevOps principles, including secure remote access, network configuration, web server deployment, and service automation in a Linux environment.
This documentation serves as a practical blueprint, demonstrating comfort with Linux command-line tools, networking fundamentals (Nmap), system services (systemctl), and scripting for basic automation.
!! IMPORTANT !! This README.md is the first part of this project and Note.md file, inside scripts folder is the second part. Make sure you check that out too.
Infrastructure Management: Successfully discover, connect to, and manage a headless Raspberry Pi over a local network.
Security & Access: Implement robust, non-password-based SSH authentication using key pairs for secure administrative access.
Web Services: Deploy and manage the high-performance Nginx web server to serve content.
Automation: Utilize Bash scripting and Linux utilities (inotifywait, systemctl) to automate service health checks and configuration management, ensuring high availability and operational efficiency.
Laptop (Ubuntu)
|
| SSH / SCP over hotspot
|
iPhone Hotspot (NAT Router)
|
| Local IP: 172.20.10.X (to be discovered)
|
Raspberry Pi (Headless)
- Nginx Server
- Automation Scripts$ mkdir raspberrypi_home_lab && cd raspberrypi_home_lab && mkdir screenshots && mkdir scripts && code README.md && git init$ git add . && git commit -m " Initial Commit" && git remote add origin https://github.com/fitandfine/raspberrypi_homelab.git && git push -u origin mainWhen running a Raspberry Pi in headless mode (no keyboard, mouse, or monitor), the only way to access it is over the network via SSH. But when your Raspberry Pi is connected through an iPhone hotspot, the hotspot UI does not show connected device IP addresses. This makes it impossible to know the Pi’s IP directly.
Solution: nmap ( Network Mapper)
nmap is a network exploration tool that scans an IP range and reports devices, open ports, and system fingerprints. It works by sending raw IP packets to target hosts and then analyzes the responses to determine:
-
Host Status: Are the target hosts up and running?
-
Open Ports: What ports are open on the host?
-
Service/Version: What services (e.g., SSH, HTTP, FTP) are running on those ports, and what versions are they?
-
OS Detection: What operating system and version is the target running?
-
Detect all devices connected to the iPhone hotspot.
-
Identify the Raspberry Pi based on open ports. (SSH → port 22)
-
Obtain the Pi’s IPv4 address so we can SSH into it.
This section details the logical process used to determine the IP address of the headless Raspberry Pi through network scanning, a crucial step in managing remote infrastructure.
The ip a | grep "inet" command was used to identify the local network interface and its assigned IP address.
| Command & Output | Explanation |
|---|---|
| ip a grep "inet" | Displays network configuration filtered for IPv4 (inet) addresses. |
inet 172.20.10.4/28 ... wlp4s0 |
This line identifies the laptop's IP as wlp4s0). The /28 CIDR notation defines the network subnet to be scanned: |
The sudo nmap -sn 172.20.10.0/28 command performed a Ping Scan (-sn) on the entire subnet to find all active devices.
| Nmap Report for |
Role | Logic for Elimination |
|---|---|---|
_gateway) |
Router | Eliminated: This is the network gateway. |
anuponlinux) |
Laptop | Eliminated: This is the scanning machine itself. |
| Unknown Host |
Deduced Target: By eliminating the router and the laptop, the remaining active host, |
To definitively prove that
| Command & Output | Verification Logic |
|---|---|
sudo nmap -sV -p 22 172.20.10.9 |
-p 22 focuses the scan on the SSH port, and -sV attempts to detect the running service version. |
PORT 22/tcp open ssh |
Confirms the required Secure Shell (SSH) service is listening. |
OpenSSH_9.2p1 -2+deb12u6 |
The service banner explicitly identifies the operating system as a Debian-based distribution (which includes Raspberry Pi OS), confirming the host is the Pi. |
Thus, through logical elimination and service banner confirmation, the Raspberry Pi's IP address was successfully identified as 
Enter the following command <user_name>@ip_address, and you will be prompted for password or linux on raspberry pi.
$ ssh [email protected]Now terminate the ssh session with exit command and create key-pair login between laptop and raspberry pi before installing nginx.
While password login is simple, it poses significant security and operational problems. SSH key-pair authentication solves these issues, making it the standard practice in professional infrastructure management.
| Feature | Password Authentication | Key-Pair Authentication | Necessity for Project Scope |
|---|---|---|---|
| Security | Susceptible to Brute-Force Attacks and dictionary attacks. Weak passwords are a single point of failure. | Uses strong, 2048-bit or higher cryptographic keys that are virtually impossible to crack. | Mandatory for security best practices. |
| Automation | Requires a manual prompt for a password or saving passwords in script files (a major security risk). | Allows for non-interactive login. Scripts (like the health checks we'll write) can run seamlessly without human intervention. | Mandatory for the "Automation" goals of this project. |
| User Experience | Requires typing a password on every login. | If using an SSH agent, allows instant, one-click access after an initial one-time passphrase entry. | Improves efficiency and reflects a professional workflow. |
Let's create a new, dedicated key (id_rsa_pi_new).
This command creates a new private key (id_rsa_pi_new) and its corresponding public key (id_rsa_pi_new.pub).
# Command: Generate a new SSH key pair using the modern Ed25519 algorithm.
# -f specifies a unique filename to prevent overwriting existing key.
$ ssh-keygen -t ed25519 -f ~/.ssh/id_rsa_pi_new- Prompt: You will be prompted to enter a passphrase. This passphrase protects the private key on your laptop and is the password you will be asked for by the laptop when you connect, not the Pi's password.
The ssh-copy-id utility securely places the public key (id_rsa_pi_new.pub) into the correct location on the Pi (~/.ssh/authorized_keys).
# Command: Upload the new public key to the Pi.
# You will be prompted for the Raspberry Pi's USER PASSWORD one last time.
$ ssh-copy-id -i ~/.ssh/id_rsa_pi_new.pub [email protected]Now, attempt to connect to the Raspberry Pi using same ssh command. This will prompt you for yout laptop's password once citing the key is locked. Then it will not prompt for it till you log out or reboot the laptop.
# Command: Connect using the new key file.
# You will be prompted for the KEY'S PASSPHRASE (if set), not the Pi's password.
$ ssh [email protected]- Result: Successful login without needing the Pi's user password confirms the secure key-based authentication is fully operational.
The infrastructure access is now secure and automated.
$ sudo apt update
$ sudo apt install nginx -y && sudo systemctl status nginxWhat happened here is a classic port conflict error. While Nginx installed successfully, it failed to start because another program was already using its required default port, TCP port 80.
# Command: Finds the Process ID (PID) using TCP port 80.
# The `fuser` utility is highly effective for this task.
$ sudo fuser 80/tcp # shows which process id is using the port 80
$ ps -p 1158 -o comm= # in this case it was the process id number 1158
$ sudo systemctl stop apache2 # process id 1158 happened to be apache2
$ sudo systemctl start nginx # nginx now started after freeing port 80 from apache2
$ sudo systemctl status nginx # shows the status of nginx ( see screenshot below)Run following commands:
$ cd /var/www/html/
$ sudo nano index.htmlPlease check inside scripts folder for some automation scripts.
There is a Note.md file, inside scripts folder, which contains description and output screenshot of the scripts running on raspberry pi. Please have a look at that too.
Make sure to take a look at make.sh file in scripts/bash and scripts/python. It will save you from making our bash scripts (.sh) executable manually and it also runs your python scripts.
$ ./make.sh <script_name>








