banner
B1ueD0g

BlueDog's Home

上班使我怨气比鬼重!
x
telegram
email

Raspberry Pi Kali Full Configuration Process

This guide details how to deploy Kali Linux (XFCE desktop environment) on a Raspberry Pi 5 in a headless manner and achieve remote access using FRP (Fast Reverse Proxy). The content covers the complete steps from preparing the image, flashing the TF card, system initialization configuration, to installing common tools, setting up the graphical interface and VNC service, as well as achieving internal network penetration for remote connection through FRP. All operations are designed for a headless environment and provide clear command line examples (with comments) and configuration file examples.

Tools Involved#

Hardware Tool List#

  1. Raspberry Pi 5 - 16GB version
    1. Official product brief of Raspberry Pi 5: https://datasheets.raspberrypi.com/rpi5/raspberry-pi-5-product-brief.pdf
    2. Mechanical module & interface drawings of Raspberry Pi 5: https://datasheets.raspberrypi.com/rpi5/raspberry-pi-5-mechanical-drawing.pdf
    3. Official getting started documentation for Raspberry Pi 5: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html
  2. Raspberry Pi 5 aluminum alloy CNC ultra-thin case - fan version (please search and purchase on Taobao)
  3. Official PD charger (The performance of Raspberry Pi 5 is higher than that of Raspberry Pi 4, and using a power supply with insufficient power may cause issues. Therefore, it is recommended to use a high-quality 5V 5A USB-C power supply)
  4. TF card - U3V30A2 (64GB or larger)
  5. Card reader

Software Tool List#

  1. Official Kali image: https://kali.download/arm-images/kali-2025.2/kali-linux-2025.2-raspberry-pi-arm64.img.xz
  2. Official Raspberry Pi imaging tool: https://downloads.raspberrypi.org/imager/
  3. VNC tool: https://www.realvnc.com/en/connect/download/viewer/ (personally recommended)
  4. FRP: https://github.com/fatedier/frp

Preparing Kali Raspberry Pi Image and Flashing TF Card#

Download the image: Go to the official Kali Linux website to obtain the latest ARM64 image file for Raspberry Pi. For example, we use the kali-linux-2025.2-raspberry-pi-arm64.img.xz image, which includes the XFCE desktop environment and supports Raspberry Pi 5 hardware. It is recommended to use a high-speed microSD TF card with a capacity of 64GB or larger to accommodate the complete system and toolset. After downloading the image, you can verify its SHA256 checksum to ensure the file is intact.

Prepare the flashing tool: Install the Raspberry Pi official imaging tool Raspberry Pi Imager (supports Windows, macOS, Linux). We can also use tools like Balena Etcher or command line dd for flashing, but Raspberry Pi Imager provides convenient pre-configuration options.

Flash the image to the TF card:

  • Insert the TF card into the card reader and connect it to the computer. Make sure to back up important data on the card or use a new card.
  • Open Raspberry Pi Imager, click the “Choose OS” button. Find “Kali Linux” in the list (it can be found under “Other specific purpose OS”). Select the 64-bit Kali Linux image that matches the Raspberry Pi 5 hardware architecture, or upload the downloaded image in “Use custom image”.
  • Click “Choose Storage” and select the target TF card. (Be very careful to check this step, do not flash the wrong card!!!)
  • (Optional) Pre-format: If you encounter write errors, you can first use tools like SD Card Formatter to fully format the TF card to FAT32/exFAT format.

Before clicking “Write”, we can pre-configure the system through Raspberry Pi Imager's Advanced Options for headless login on boot.

Using Raspberry Pi Imager to Write the Image and Configure Pre-set Options#

Open Advanced Configuration: In Raspberry Pi Imager, after selecting the image and storage device, click the gear icon in the window (or use the shortcut Ctrl+Shift+X) to open the advanced options menu. Raspberry Pi Imager provides a series of preset configuration items, making it convenient for us to write system configurations during flashing:

image-20250710223232323

  • Enable SSH: Check “Enable SSH” in “Services”, select to allow login with password authentication. This will automatically enable the SSH service when the system starts for the first time.
    image-20250710223212345
  • Set Hostname: Enter the system hostname in “Set hostname”, for example, kali-pi, to facilitate accessing the Raspberry Pi by name within the local network.
  • Set Default Username/Password: Fill in the default account (for example, username kali) and password (for example, kali). The default username/password for Kali is kali/kali. If using a custom username, note that the Kali image may automatically have the kali user, so it is recommended to keep the default to simplify the process.
  • Configure Wi-Fi: Fill in the SSID (wireless name) and password of the Wi-Fi network, and select the Wi-Fi country/region code. The country code is important and should match your Wi-Fi location (for example, in China, you can fill in CN). This will generate Wi-Fi configuration so that the Raspberry Pi automatically connects to the wireless network on startup.
  • Region and Localization: Set the local language and keyboard, choose the keyboard layout as “us” (English), and select the timezone as “Asia/Shanghai” or the corresponding timezone. Correct regional settings help the system display Chinese and use the correct keyboard layout.
    image-20250710223159693

After completing the configuration, click “Save”, then click “Write” to start flashing the image and apply the above preset options.

Note: According to community experience, the official Kali Linux image does not fully support the automatic pre-configuration feature of Raspberry Pi Imager. This means that even if SSH and Wi-Fi are set in Imager, they may not take effect after the first boot. To ensure remote connection without a display, we can take a manual approach to assist in configuring SSH and Wi-Fi (see below).

Wait for the writing to complete: The flashing process may take several minutes to over ten minutes. After completion, Imager will verify the writing result. After successful flashing, do not rush to remove the card; we still need to perform some manual configurations (especially to ensure SSH is enabled and Wi-Fi configuration is correct).

image-20250710224339976

Manual Configuration Before First Boot (Enable SSH and Wi-Fi)#

Since the Kali Linux image defaults to disabling SSH and cannot automatically configure Wi-Fi through Raspberry Pi Imager on the first boot, it is recommended to perform the following manual configuration before inserting the Raspberry Pi and powering it on to ensure the system can connect to the network and allow SSH login:

  • Mount the partition: After flashing is complete, two new partitions will appear on the computer: one named boot (FAT32) and the other is the Linux root filesystem partition (ext4, which may be invisible in Windows). We mainly operate on the boot partition, which is the /boot partition.

  • Enable SSH: Create an empty file named ssh (without an extension) in the root directory of the boot partition. This will trigger Kali to enable the SSH service on the first boot. In Windows, you can create a new text file and name it “ssh” (ensure there is no .txt suffix). In Linux/macOS, you can execute the command (assuming boot is mounted at /mnt/boot):

    # Create an empty ssh file in the boot partition to enable SSH
    sudo touch /mnt/boot/ssh
    
  • Configure Wi-Fi: If you need the Raspberry Pi to connect to the internet via Wi-Fi, create a wpa_supplicant.conf file in the root directory of the boot partition and fill in the wireless network configuration. The file content format is as follows (please modify according to actual Wi-Fi information):

    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
    update_config=1
    country=CN  # Change CN to your country code, such as US, UK, etc.
    
    network={
        ssid="Your_WiFi_SSID"        # Wi-Fi name
        psk="Your_WiFi_Password"     # Wi-Fi password
        key_mgmt=WPA-PSK             # Encryption type, WPA2 commonly uses WPA-PSK
    }
    
  • Replace Your_WiFi_SSID and Your_WiFi_Password in the above content with the actual wireless network name and password. When saving, ensure the file name is wpa_supplicant.conf (do not have a .txt extension). Kali typically moves this configuration file to /etc/wpa_supplicant/ during boot and uses it to connect to Wi-Fi.

After completing the above steps, eject and remove the TF card. Insert the card into the Raspberry Pi 5, connect the power, and boot it up. Wait about 1-2 minutes for the system to complete the first boot configuration.

At the same time, it is recommended to complete DHCP static IP allocation in your router.

image-20250711111216799

First Boot and SSH Remote Login to Kali#

After powering on the Raspberry Pi, it will attempt to connect to Wi-Fi and enable the SSH service based on the previous configuration. Next, we need to log into the Raspberry Pi's Kali system via SSH from another computer:

  • Find the Raspberry Pi IP address: Obtaining the device IP in a headless environment is the primary challenge. You can log into the router's management interface to check for newly connected devices (based on the hostname kali-pi or check the new DHCP list), or use a local network scanning tool like nmap to scan the subnet to find hosts with an open port 22. Another method is to use the mDNS hostname (if the network supports it) and try to SSH directly to kali-pi.local (provided that DNS resolution is available on the network or the computer has Bonjour service installed).

  • Connect using SSH: Execute in the terminal or command prompt (replace with the actual Raspberry Pi IP address):

    ssh kali@<IP>
    
  • If you used our preset username/password (or the Kali default kali/kali), you will be prompted to enter the password to log in. The first connection will require accepting the host key.

  • Change Password: After the first login, for security reasons, please change the default account password promptly:

    sudo passwd kali
    
    • Enter the new password as prompted.

At this point, you have successfully logged into the Kali system on the Raspberry Pi via SSH. You can now proceed with system configuration and software installation.

Tip: If you are unable to SSH into the Raspberry Pi at this time, please refer to the Common Issues and Troubleshooting Suggestions section at the end. Common reasons include SSH not being successfully enabled, Wi-Fi not being connected, etc. You can fix this by connecting via a wired network or reconfiguring the above files.

Change Software Source to Domestic Mirror (Improve Update Speed)#

The default software source for Kali Linux is on foreign servers, and updating directly in China may be slow or even fail. We can switch the software source to a domestic mirror (such as Tsinghua University's open-source mirror site) to improve speed. The steps are as follows:

  1. Backup the source list: Before editing the source list file, it is recommended to back up the original file:

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
    
  2. Edit /etc/apt/sources.list: Use editors like vim or nano to open this file, comment out the original official source lines, and add the domestic source address at the top of the file. For example, add Tsinghua University's Kali mirror source:

    sudo nano /etc/apt/sources.list
    
    # The USTC source, Ali source, etc. can also be used; here we take Tsinghua TUNA source as an example
    # Tsinghua University Kali mirror source
    deb https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
    deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free non-free-firmware
    
  3. The above two lines specify the addresses for binary package sources and source sources, respectively. The kali-rolling is Kali's rolling update branch, which includes main (main), contrib (contributed), non-free (non-free), and non-free-firmware (non-free firmware) components. Ensure that all components are included according to actual needs to avoid missing drivers or tools.

  4. Update APT key (if needed): If you encounter invalid public key errors when running updates after changing sources, you can execute the following command to import the Kali official repository public key:

    sudo wget -q -O - https://archive.kali.org/archive-key.asc | sudo apt-key add -
    

    Then run the update command again, and save and exit the editor after making the changes.

Update the System and Upgrade Packages#

After changing the source, first execute a system update to ensure the latest patches and indexes are installed:

# Update package index
sudo apt update -y
# Upgrade installed packages
sudo apt -y full-upgrade -y

The above commands will refresh the APT package list and apply all available upgrades. In Kali (Debian), it is recommended to use full-upgrade (or dist-upgrade) to handle possible dependency changes. The process may take some time, especially if the image version is not the latest. Please be patient and wait for completion; if prompted, you can press Y to confirm or q to skip viewing more detailed information.

After the system upgrade is complete, it is recommended to reboot the Raspberry Pi once (sudo reboot) to ensure that kernel updates and other changes take effect. After rebooting, log in again via SSH to continue with the subsequent steps.

Install the kali-linux-everything Toolset#

Kali Linux provides several meta-packages for toolsets, among which kali-linux-everything includes “almost all” tools available in Kali. If there is sufficient storage space and bandwidth, we can install this toolset with one command to have a complete penetration testing toolset on the Raspberry Pi.

sudo apt install -y kali-linux-everything
Version NameBrief DescriptionUsage Scenario
Installer / DefaultStandard installation version, containing basic system and common penetration testing toolsGeneral penetration testing environment, suitable for online updates
Live ISOBootable without installation (includes GUI and some tools)Temporary testing, USB portable system, forensics
NetinstMinimal installation, requires network to pull componentsHighly customizable installation, suitable for lightweight VMs or automated deployment
LargeInstallation package containing most mainstream Kali toolsCommonly used by penetration testers, almost no additional installation required after deployment
EverythingContains all tools in the Kali repository, installation image exceeds 20GB+Offline environment deployment, large target environments, complete toolchain preparation
Function ModuleDefault/InstallerLargeEverything
kali-linux-default toolset
top10, wireless, web, etc. categorized tools⛔️(manual installation)✅(includes most)✅(all)
All Kali meta-packages⛔️partial✅ all
Total number of tools (rough estimate)100–200300–400600+

This command may download several GB of data (the complete installation size may exceed 20GB), so please ensure the network is stable and there is sufficient remaining space on the TF card (this is the reason for installing a 64GB or larger card). Depending on the network speed, this process may take a long time. During the installation, APT will automatically handle dependencies and configure software; if there are interactive prompts, choose the default or as needed.

After completion, Kali on the Raspberry Pi will have a complete toolset, ready for various security testing.

Configure Graphical Interface and VNC Service (Remote Desktop)#

In a headless situation, we may still need to use Kali's graphical desktop (XFCE) to run certain tools or obtain a complete desktop experience. To do this, we will configure the system to start the graphical interface on boot and achieve remote desktop access via VNC.

Set Default Startup to Graphical Interface#

The Kali Linux Raspberry Pi image may default to starting in text console to save resources. If we want the system to enter the XFCE desktop environment immediately after booting, we need to adjust the system target to graphical mode:

# Set the system default runlevel to graphical interface
sudo systemctl set-default graphical.target

After executing the above command, the system will attempt to start the display manager (such as LightDM) to enter the graphical interface by default. Since we are in a headless environment, if the Raspberry Pi is not connected to a display, the X server may not actually display the interface by default. However, we can still create a virtual display via VNC.

Note: If the Raspberry Pi always has no physical display, graphical.target will start the desktop service, but without an HDMI connection, it may not create the default :0 display output. We will solve this issue later through VNC virtual desktop. If you need to connect a display for local operations in the future, you can keep this setting for easy direct access to the desktop.

Install TigerVNC Service#

TigerVNC is a well-performing VNC server implementation. We choose it to run a virtual desktop session on the Raspberry Pi. Installation command:

sudo apt install -y xfce4 xfce4-goodies tigervnc-standalone-server tigervnc-common autocutsel
  • tigervnc-standalone-server installs the TigerVNC server program.
  • tigervnc-common provides related common files.
  • autocutsel is a tool used to synchronize the clipboard between the VNC session and the local clipboard (copy/paste).

After installation, set the VNC access password and initialize the configuration:

# Switch to a normal user (if currently logged in as root, switch back to kali user)
exit            # Ensure operations are performed under kali user

# Set VNC password (will prompt to enter and confirm password)
vncpasswd

# First start the VNC service (generate configuration file and create VNC session :1)
vncserver :1

When running vncserver :1 for the first time, it will ask to set an access password (no more than 8 characters) and optionally set a "read-only" password (here choose n, no need for a read-only password). It will then output similar information indicating that a VNC desktop numbered:1 has been started (corresponding to TCP port 5901).

Since the VNC service starts on port 5900, and we need to create a new port for the desktop environment, here 1 means +1, which is on port 5901; if it is vncserver :2, it would be port 5902, and so on.

New 'X' desktop is kali:1
Creating default startup script /home/kali/.vnc/xstartup
Starting applications specified in /home/kali/.vnc/xstartup
Log file is /home/kali/.vnc/kali:1.log

This indicates that TigerVNC has started a virtual desktop session in the background. By default, this virtual desktop may only have a gray background and an X terminal (or may exit due to incorrect configuration). Next, we will configure it to start the XFCE desktop environment.

Stop the VNC session just started:

vncserver -kill :1

This will terminate the session so that we can edit the configuration file and restart it.

Configure VNC to Start XFCE Desktop Session#

The default startup script for TigerVNC (and TightVNC) is located at ~/.vnc/xstartup, which has been generated during the first run. We need to modify it to start the XFCE4 desktop environment; otherwise, the VNC connection may only show a gray screen and an X cursor. Edit the file:

sudo nano ~/.vnc/xstartup

Replace its content with the following:

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
startxfce4 &   # Start XFCE4 desktop session
autocutsel -fork  # Start clipboard synchronization

The above configuration ensures that every time a VNC virtual session starts, it clears any possible residual session environment variables, then starts the XFCE4 desktop in the background and runs autocutsel to support clipboard sharing. Save the file and exit the editor.

Grant executable permissions to the xstartup script:

sudo chmod +x ~/.vnc/xstartup

Note: The xstartup file permissions must be executable; otherwise, TigerVNC will ignore it, preventing the XFCE desktop from starting.

Manually Test VNC Connection#

Now manually start the VNC service to test if remote desktop access can be achieved:

# Start another VNC session :1
vncserver :1 -geometry 1280x800 -depth 24

Here, the resolution is specified as 1280x800 with a color depth of 24 bits. You can adjust the -geometry parameter to set an appropriate virtual screen resolution as needed (common resolutions include 1920x1080, 2560x1440, etc.).

After successful startup, use VNC Viewer (such as TigerVNC Viewer, RealVNC Viewer, etc.) on your PC to connect to the Raspberry Pi's IP and port, for example:

192.168.1.25:5901

When prompted for a password, enter the previously set VNC password, and you will see the Kali XFCE desktop environment. At this point, you are remotely using the graphical interface on the headless Raspberry Pi.

If a gray or black screen appears after connecting, it may be due to incorrect xstartup configuration or lack of executable permissions. Please check if the content of ~/.vnc/xstartup matches the above and is executable. Also, ensure that you have first run vncserver -kill before editing and restarting; otherwise, the old instance will not read the new configuration.

vncserver -kill :1

image-20250711092623134

Set VNC Service to Start on Boot#

To automatically start the VNC service each time the Raspberry Pi boots (without manual commands), we can set up a systemd service to manage the VNC Server. Create a new systemd unit file on Kali:

sudo nano /etc/systemd/system/vncserver@.service

Fill in the following content and save:

[Unit]
Description=Start TightVNC (TigerVNC) server at startup
After=syslog.target network.target

[Service]
Type=forking
User=bluedog
Group=bluedog
WorkingDirectory=/home/bluedog
PIDFile=/home/bluedog/.vnc/%H:%i.pid
ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
ExecStart=/usr/bin/vncserver -depth 24 -geometry 1920x1080 :%i
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

In the above configuration, %i represents the instance number, for example, vncserver@1.service will replace %i with 1, thus starting the :1 session. We set the service to run as the kali user, attempt to kill any residual :1 instances before starting, and set the resolution to 1920x1080 and color depth to 24 bits, which can be modified as needed.

After saving the file, refresh the systemd configuration and start and enable the service:

sudo systemctl daemon-reload
sudo systemctl start vncserver@1.service    # Start VNC service instance :1
sudo systemctl enable vncserver@1.service   # Set to start on boot

Now, even if the Raspberry Pi restarts, the system will automatically start the VNC service during the startup process, allowing you to connect to the desktop remotely at any time.

Tip: The default VNC service listens on port 5901 on all local interfaces and is accessible only within the local network. If you need to access it over the internet, it is recommended to combine the following FRP internal penetration configuration or ensure the network environment is secure and set a complex VNC password.

Dynamically Adjust VNC Resolution#

The default VNC client does not support dynamically adjusting the VNC resolution to fit the client's screen size. However, it can be modified manually.

xrandr

image-20250711093944551

It will display the currently supported resolutions.

xrandr --output VNC-0 --mode 2560x1440

Executing this will adjust the current VNC window size to the corresponding resolution.

Configure FRP for Remote Access (Internal Penetration)#

In many practical scenarios, the Raspberry Pi may be located in an internal network or lack a public IP, making it impossible to connect directly via the internet. We can use FRP to achieve internal penetration, mapping the Raspberry Pi's SSH and VNC services to a public server for remote access at any time.

FRP (Fast Reverse Proxy) consists of a client and a server:

  • FRP server (frps) is deployed on a server with a public IP or cloud server, listening for connections from clients and opening ports for remote access.
  • FRP client (frpc) is deployed on internal devices like the Raspberry Pi, actively connecting to the FRP server and mapping local service ports outward.

Below, we assume you have a server with a fixed public IP or domain name available to act as the FRP server (or use a cloud server). We will use this server as a relay to expose the Raspberry Pi's SSH and VNC ports.

Configure FRP Server (frps) on the Server#

(If the FRP server is already running, you can skip this section.) On the cloud server:

  1. Download frp: Obtain the latest version from the FRP official repository. You can find the latest version download link by browsing https://github.com/fatedier/frp/releases. For example, here we assume the latest version is v0.61.0, corresponding to the Linux amd64 platform:

    wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
    tar -xzf frp_0.61.0_linux_amd64.tar.gz
    cd frp_0.61.0_linux_amd64
    
  2. Configure frps: In the extracted directory, find frps.toml (create it if it does not exist). Write the following configuration:

########################################
#  Fast Reverse Proxy Server (frps)    #                                     
#  Location: Alibaba Cloud ECS 4*.**.**.**0         #
########################################

# [common]
# ───────── Basic Listening ─────────
bindAddr = "0.0.0.0"          # Listen on all IPv4 (change to ":::" if IPv6 is needed)
bindPort = 7501               # The serverPort on the frpc side must match and the corresponding port must be opened on the cloud server
# ───────── Authentication Token ─────────
auth.token = "Set your own password here"        # The client auth.token must remain the same
# ───────── Domain Forwarding Port ─────
# Domain resolution is not yet enabled, directly close 80/443 to avoid multiple open ports
# vhostHTTPPort  = 0
# vhostHTTPSPort = 0
# ───────── Log Configuration ─────────
# logFile    = "/root/frp/frps.log"   # Custom log path
# logLevel   = "info"                 # Options: trace, debug, info, warn, error
# logMaxDays = 7                      # Log retention days
# ───────── Optional: Dashboard ─────
# dashboardPort = 7501             # Web UI port
# dashboardUser = "Set your own username"
# dashboardPwd  = "Set your own password"
# ───────── Optional: TLS Reinforcement ────
# If mTLS is needed, enable:
# authenticationMethod = "token,tls"
# tlsOnly              = true
# Certificate-related fields refer to official examples

subdomainHost = "Set your own domain here if any"
  1. Start frps: You can run it directly in the foreground:
sudo ./frps -c ./frps/frps.toml

Or run it as a background service:

nohup ./frps -c ./frps/frps.toml &>/var/log/frps.log &
  1. Ensure that the server's firewall opens the required ports (for example, TCP 7000, and the ports to be mapped out, such as SSH's 6000, VNC's 6001, etc.).

  2. Configure frps to start on boot: Create a new systemd service /etc/systemd/system/frps.service, write the following content:

    [Unit]
    Description=Fast Reverse Proxy Server (frps)
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/root/frp/frps -c /root/frp/frps.toml               # Note your own path!
    Restart=on-failure
    LimitNOFILE=65535
    
    [Install]
    WantedBy=multi-user.target
    

    After saving, enable the service:

    sudo systemctl daemon-reload
    sudo systemctl enable frps
    sudo systemctl start frps
    

Configure FRP Client (frpc) on the Raspberry Pi#

Return to our Kali Raspberry Pi:

  1. Download frpc: Download the Linux ARM64 version of the FRP client according to the Raspberry Pi architecture. The version must match the server.
cd /tmp
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_arm64.tar.gz
tar xzf frp_0.61.0_linux_arm64.tar.gz
cd frp_0.61.0_linux_arm64
sudo cp frpc /usr/bin/              # Install the frpc executable file to the path
sudo cp frpc.toml /etc/frpc/frpc.toml      # Copy the default configuration file to /etc

The above uses v0.61.0 as an example; please replace it with the actual latest version number. After extracting, we place the frpc executable file in /usr/bin for easy direct execution; the example configuration is renamed and placed in /etc for unified management.

  1. Configure frpc: Edit the /etc/frpc/frpc.toml file and modify it according to actual needs. For example, if we want to map the Raspberry Pi's SSH (port 22) and VNC (port 5901) to the server's corresponding ports, the configuration can be as follows:
###############################################################################
#  Fast Reverse Proxy Client (frpc)
#  Host: Raspberry Pi Kali — 192.168.**.** (please switch to your own IP address)
###############################################################################

#############################
# frps connection information
#############################
serverAddr     = "4*.**.**.**0"   # Alibaba Cloud public IP
serverPort     = 7501               # frps.bindPort
loginFailExit  = false              # Do not exit on disconnection, keep reconnecting

[auth]
  method = "token"
  token  = "Set your own password here"        # Keep consistent with frps.token

#############################
# Port mapping (TCP)
#############################
[[proxies]]                # SSH
  name       = "kalissh"
  type       = "tcp"
  localIP    = "192.168.**.**"
  localPort  = 22
  remotePort = 5022          # Already opened in frps.allowPorts & security group

[[proxies]]                # VNC
  name       = "kalivnc"
  type       = "tcp"
  localIP    = "127.0.0.1" (must use loopback address here!!!)
  localPort  = 5901
  remotePort = 5901          # Already opened in frps.allowPorts & security group

In the [common] section, fill in the FRP server address, port, and authentication token, etc. Then define two tunnels: [ssh] and [vnc], which expose the local SSH service (192.168.*0.**) and VNC service (127.0.0.1:5901) through FRP. The remote_port specifies the port number opened on the FRP server; you can change it as needed, but it must correspond to the server firewall configuration.

  1. Configure frpc to start on boot: Create a new systemd service /etc/systemd/system/frpc.service, write the following content:
[Unit]
Description=Fast Reverse Proxy Client (frpc)
After=network.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/home/username/frp/frpc -c /home/username/frp/frpc.toml   # Note your own path!
Restart=always
RestartSec=3
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

After saving, enable the service:

sudo systemctl daemon-reload
sudo systemctl enable frpc
sudo systemctl start frpc

This way, the Raspberry Pi will automatically run frpc at startup and connect to the FRP server once the network is ready.

  1. Verify the connection: Run sudo systemctl status frpc on the Raspberry Pi to check the logs and confirm that it has successfully connected to the server without errors. If there are issues, check /var/log/syslog or /var/log/frpc.log (if log output is set).

On the server, you can also check the frps logs or use ss -tnl to confirm that the corresponding ports are listening.

  1. Remote Access: Now, in any network environment, you can manage the Raspberry Pi by accessing FRP server's IP/domain + port:
  • SSH access: ssh kali@ -p 6000 (forwarded to the Raspberry Pi's port 22 through FRP's 5022 port). You can add this combination to ~/.ssh/config for quick connection.
  • VNC access: Connect to :6001 in VNC Viewer, which forwards to the Raspberry Pi's 5901 through the FRP server's 6001 port. Enter the previously set VNC password to remotely control the Raspberry Pi's desktop.

Through FRP, the communication will be verified with the specified token and (if TLS is enabled) encrypted during transmission, ensuring a certain level of security. For added security, it is recommended to use key authentication for SSH and disable password login, among other hardening measures.

Now, regardless of where the Raspberry Pi is located (even in environments with NAT restrictions like cellular networks), as long as the FRP client and server maintain a connection, we can remotely SSH or VNC access the Kali system on the Raspberry Pi at any time through the FRP tunnel.

Other Software and Tweaks#

Customizing the Login Welcome Screen#

image-20250711110405304

ComponentFunction
/etc/update-motd.d/*A series of executable scripts that run in numerical order, generating a dynamic MOTD.
/etc/motdStatic MOTD text. If content exists, it will be appended after the dynamic MOTD.
pam_lastlog.soAutomatically outputs Last login records called by PAM.
/etc/issue.net + Banner directiveSSH session banner. Can reuse ASCII Banner for local/remote consistency.

File Structure and Execution Order

/etc/update-motd.d/
├── 00-header     # ASCII Banner
├── 10-sysinfo    # System status
└── 20-network    # Network information

The numerical prefix determines the execution order; the output order is the display order.

Create ASCII Banner#

  1. Online Generation

  2. Local Generation

figlet -f slant "BlueDog"
toilet -f big -F metal "BlueDog"

Copy the generated character art for later use.

Write 00-header#

sudo tee /etc/update-motd.d/00-header >/dev/null <<'EOF'
#!/bin/bash
clear   # Prevent screen residue

# ---------------- ASCII Banner -----------------
cat <<'BANNER'
 ,---,.    ,--,                                  ,---,                            
  ,'  .'  \ ,--.'|                                .'  .' `\                          
,---.' .' | |  | :             ,--,             ,---.'     \     ,---.               
|   |  |: | :  : '           ,'_ /|             |   |  .`\  |   '   ,'\    ,----._,. 
:   :  :  / |  ' |      .--. |  | :     ,---.   :   : |  '  |  /   /   |  /   /  ' / 
:   |    ;  '  | |    ,'_ /| :  . |    /     \  |   ' '  ;  : .   ; ,. : |   :     | 
|   :     \ |  | :    |  ' | |  . .   /    /  | '   | ;  .  | '   | |: : |   | .\  . 
|   |   . | '  : |__  |  | ' |  | |  .    ' / | |   | :  |  ' '   | .; : .   ; ';  | 
'   :  '; | |  | '.'| :  | : ;  ; |  '   ;   /| '   : | /  ;  |   :    | '   .   . | 
|   |  | ;  ;  :    ; '  :  `--'   \ '   |  / | |   | '` ,/    \   \  /   `---`-'| | 
|   :   /   |  ,   /  :  ,      .-./ |   :    | ;   :  .'       `----'    .'__/\_: | 
|   | ,'     ---`-'    `--`----'      \   \  /  |   ,.'                   |   :    : 
`----'                                 `----'   '---'                      \   \  /  
                                                                            `--`-'   
BANNER

echo "-------------------------------------------------------------------------------------"
EOF
sudo chmod +x /etc/update-motd.d/00-header

Write 10-sysinfo#

sudo tee /etc/update-motd.d/10-sysinfo >/dev/null <<'EOF'
#!/bin/bash
OS="$(lsb_release -ds)"
KERNEL="$(uname -r)"
MEM_USED="$(free -h --si | awk 'NR==2 {print $3 "/" $2}')"
DISK_ROOT="$(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 ")"}')"
CPU_TEMP="$(vcgencmd measure_temp | cut -d= -f2)"

printf "🖥  System:  %s  |  Kernel: %s\n" "$OS" "$KERNEL"
printf "💾  Memory:  %s\n" "$MEM_USED"
printf "📦  Disk:  %s\n" "$DISK_ROOT"
printf "🌡  Temperature:  %s\n" "$CPU_TEMP"
echo "-------------------------------------------------------------------------------------"
EOF
sudo chmod +x /etc/update-motd.d/10-sysinfo

Write 20-network#

sudo tee /etc/update-motd.d/20-network >/dev/null <<'EOF'
#!/bin/bash
IP=$(hostname -I | awk '{print $1}')
SSID=$(iwgetid -r 2>/dev/null || echo "Offline")

printf "🌐  IP Address: %s\n" "$IP"
printf "📶  Wi-Fi SSID: %s\n" "$SSID"
echo "-------------------------------------------------------------------------------------"
EOF
sudo chmod +x /etc/update-motd.d/20-network

Clear Default /etc/motd#

sudo mv /etc/motd /etc/motd.bak   # Backup
sudo touch /etc/motd              # Create an empty file

This retains Last login while removing GPL/Warranty statements.


SSH Banner Synchronization (Optional)#

sudo cp /etc/update-motd.d/00-header /etc/issue.net
sudo sed -i 's@^#Banner none@Banner /etc/issue.net@' /etc/ssh/sshd_config
sudo systemctl restart ssh

Fan & Speed Control#

First, the Raspberry Pi 5's fan scheduling starts at 65 degrees; it generally does not turn on when there are no tasks and large model tasks.

Moreover, since gpiozero + RPi.GPIO is not yet fully supported on Raspberry Pi 5, errors will occur when accessing GPIO.

image-20250711111602896

Therefore, we can only enable the fan automatic speed control function of the RP1 controller through parameters in config.txt, which natively supports 1 to 3 temperature control levels (temperature trigger + PWM duty cycle combination).

Multi-level Temperature Control Fan Configuration Method (config.txt)

Add the following configuration to /boot/firmware/config.txt (this path is used for Raspberry Pi 5):

# Raspberry Pi 5 fan three-level automatic speed control configuration
dtparam=cooling_fan=on

# Level 1: Starts at 40°C, fan runs at 60% speed (153/255)
dtparam=fan_temp1=40000,fan_temp1_hyst=5000,fan_temp1_speed=153

# Level 2: Starts at 50°C, fan runs at 80% speed (204/255)
dtparam=fan_temp2=50000,fan_temp2_hyst=5000,fan_temp2_speed=204

# Level 3: Starts at 55°C, fan runs at full speed (255/255)
dtparam=fan_temp3=55000,fan_temp3_hyst=5000,fan_temp3_speed=255

The core mechanism is that when the CPU temperature exceeds a certain threshold, it switches to the corresponding speed and will not drop back to a lower level until the temperature falls below the corresponding hysteresis threshold.

You can also set hysteresis parameters (recommended):

dtparam=fan_temp3_hyst=5000   # Stop at 50°C for the third level

Wi-Fi Multi-Network Automatic Switching Settings (Home + Mobile Hotspot)#

Kali defaults to using wpa_supplicant to manage Wi-Fi.

  1. Edit the Wi-Fi configuration file:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Add two networks (automatically switch by priority):

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=CN

network={
    ssid="Your Home WiFi"
    psk="Your Home Password"
    priority=10
}

network={
    ssid="Your Mobile Hotspot"
    psk="Your Hotspot Password"
    priority=5
}
  • The higher the priority number, the more preferred the connection;
  • Automatic connection will prioritize the above Wi-Fi in available scenarios.

After saving, restart the network service or reboot directly:

sudo wpa_cli -i wlan0 reconfigure

Install Input Method#

Install Google Pinyin and Fcitx

sudo apt install fcitx fcitx-googlepinyin

image-20250711101408562

Switch input method framework

im-config

image-20250711101523278

After completing the input method, be sure to restart the system for it to take effect.

image-20250711103900755

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.