Running RF Swift

Running RF Swift

Important settings

RF Swift provides a streamlined command-line interface to manage containers for RF and hardware security applications. This guide covers essential commands and workflows.

On Linux, unless you are using Docker Desktop, you will need to use sudo with the rfswift command for operations that require elevated privileges.

To avoid using sudo for every Docker command, add your user to the docker group:

sudo usermod -aG docker $USER
newgrp docker

Command Overview

Let’s explore the available commands with rfswift --help:

  888~-_   888~~        ,d88~~\                ,e,   88~\   d8   
  888   \  888___       8888    Y88b    e    /  "  _888__ _d88__ 
  888    | 888          'Y88b    Y88b  d8b  /  888  888    888   
  888   /  888           'Y88b,   Y888/Y88b/   888  888    888   
  888_-~   888             8888    Y8/  Y8/    888  888    888   
  888 ~-_  888          \__88P'     Y    Y     888  888    "88_/       

                RF toolbox for HAMs and professionals                                                                             

rfswift is THE toolbox for any HAM & radiocommunications and hardware professionals

Usage:
  rfswift [flags]
  rfswift [command]

Available Commands:
  bindings     Manage devices and volumes bindings
  build        Build an image from a recipe
  capabilities Manage container capabilities
  cgroups      Manage container cgroup rules
  cleanup      Clean up containers and images
  commit       Commit a container
  completion   Generate and install completion script
  delete       Delete an rfswift images
  download     Download and save an image to tar.gz
  exec         Exec a command
  export       Export containers or images
  help         Help about any command
  host         Host configuration
  images       RF Swift images management remote/local
  import       Import containers or images
  install      Install function script
  last         Last container run
  log          Record and replay terminal sessions
  ports        Manage container ports
  realtime     Manage realtime mode for SDR operations
  remove       Remove a container
  rename       Rename a container
  retag        Rename an image
  run          Create and run a program
  stop         Stop a container
  ulimits      Manage container ulimits
  update       Update RF Swift
  upgrade      Upgrade container to a new/latest/another image

Flags:
  -q, --disconnect   Don't query updates (disconnected mode)
  -h, --help         help for rfswift

Use "rfswift [command] --help" for more information about a command.

Privilege requirements by platform:

  • Linux: sudo is required for most container operations when not using Docker Desktop
  • Windows/macOS: With Docker Desktop or OrbStack, sudo is not necessary
  • Windows: Commands related to USB binding require Administrator privileges

Core Workflows

1. Keeping RF Swift Updated

RF Swift automatically checks for updates when launched:

[!] You are running version: 0.4.8 (Obsolete)

You can then trigger updates:

rfswift update

[!] Current version: 0.6.5-rc3
Latest version: v0.6.5-rc4
[!] Your current version is obsolete. Please update to version: v0.6.5-rc4
[i] Do you want to update to the latest version? (yes/no): 
yes
[i] Latest release download URL: https://github.com/PentHertz/RF-Swift/releases/download/v0.6.5-rc4/rfswift_Linux_x86_64.tar.gz
4.58 MiB / 4.58 MiB [----------------------------------------------------------------------------------------------------------------------------------------] 100.00%%
[+] File downloaded, extracted, and replaced successfully.

If you don’t want to make any requests over the internet, you can also use -q or --disconnect option when using rswift.

2. Image Management

Customizing Image Tags

You can rename image tags for convenience or to match your default configuration:

rfswift retag -i penthertz/rfswiftdev:sdr_full_amd64 -t myrfswift:latest
[+] You are running version: 0.4.9 (Up to date)
[+] Image renamed!

This allows you to use the default tag in your configuration file:

cat /home/username/.config/rfswift/config.ini
[general]
imagename = myrfswift:latest
...
type C:\Users\username\AppData\Roaming\rfswift\config.ini
[general]
imagename = myrfswift:latest
...
cat /Users/username/.config/rfswift/config.ini
[general]
imagename = myrfswift:latest
...

With the default tag set, you can simplify the run command:

rfswift run -n my_container  # Equivalent to: rfswift run -i myrfswift:latest -n my_container
Changing an image’s tag makes it a “custom” image in RF Swift, which means it won’t receive automatic updates from the official registry.

3. Container Management

Creating and Running Containers

Create a new container from an image:

rfswift run -i sdr_full -n my_sdr_container

With Realtime Mode for SDR Operations:

For optimal SDR performance with reduced buffer underruns, use the --realtime flag:

rfswift run -i sdr_full -n my_sdr_container --realtime

This automatically configures real-time scheduling priority, memory locking, and the SYS_NICE capability.

Recording Container Sessions:

RF Swift includes built-in session recording for documentation, debugging, or training purposes:

# Record with auto-generated filename
rfswift run -i sdr_full -n my_sdr_container --record

# Record with custom filename
rfswift run -i sdr_full -n my_sdr_container --record --record-output my-session.cast

During recording, your terminal title will display “🔴 RECORDING - RF Swift” as a visual reminder.

Session recordings use the asciinema format (.cast files) which can be replayed, shared, or even uploaded to asciinema.org for embedding in documentation.

Container Listing and Selection

If you forget container names, use the last command:

rfswift last
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ℹ️  Up-to-date                                                                                    │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ You are running the latest version: 0.6.0-dev                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
  🤖 Last Run Containers                                                                                                                   
┌───────────────────────────┬─────────────────────────────┬───────────────────────────────────────────────────────┬──────────────┬──────────┐
│ Created                   │ Image Tag (ID)              │ Container Name                                        │ Container ID │ Command  │
├───────────────────────────┼─────────────────────────────┼───────────────────────────────────────────────────────┼──────────────┼──────────┤
│ 2025-04-11T16:47:02+02:00 │ penthertz/rfswift_noble:hardware  │ hardware                                              │ b6e43a87e1f6 │ /bin/zsh │
├───────────────────────────┼─────────────────────────────┼───────────────────────────────────────────────────────┼──────────────┼──────────┤
│ 2025-04-11T16:23:43+02:00 │ penthertz/rfswift_noble:bluetooth │ missionbluetooth                                      │ 3d92cb59560f │ /bin/zsh │
├───────────────────────────┼─────────────────────────────┼───────────────────────────────────────────────────────┼──────────────┼──────────┤
│ 2025-04-11T16:18:22+02:00 │ penthertz/rfswift_noble:rfid      │ missionrfid2                                          │ 50cbccef53f5 │ /bin/zsh │
├───────────────────────────┼─────────────────────────────┼───────────────────────────────────────────────────────┼──────────────┼──────────┤
...

Restarting Existing Containers

To restart the most recently used container:

rfswift exec

To restart a specific container by name:

rfswift exec -c my_sdr_container

Recording Exec Sessions:

You can also record when entering existing containers:

# Record with auto-generated filename
rfswift exec -c my_sdr_container --record

# Record with custom filename and working directory
rfswift exec -c my_sdr_container -w /root/projects --record --record-output debug-session.cast

Container Lifecycle Management

Save container changes as a new image:

rfswift commit -c my_container -i my_new_image

Rename a container:

rfswift rename -n old_name -d new_name

Remove a container:

rfswift remove -c container_name

Delete an image:

rfswift delete -c penthertz/rfswift_noble:tag_name

4. Session Recording and Playback

RF Swift provides comprehensive session recording capabilities for documentation, debugging, training, and compliance purposes.

Recording Sessions

Record your container sessions automatically:

# Record during container creation
rfswift run -i sdr_full -n my_container --record

# Record when entering existing container
rfswift exec -c my_container --record

# Specify custom output filename
rfswift run -i sdr_full -n my_container --record --record-output pentest-session.cast

What Gets Recorded:

  • All terminal input and output
  • Command execution and results
  • Tool outputs and GUI application launches
  • Timing information for accurate playback

Recording Format:

  • Sessions are saved as .cast files (asciinema format)
  • Compatible with asciinema.org for sharing
  • Can be replayed at variable speeds
  • Lightweight text-based format

Replaying Sessions

Play back recorded sessions for review or demonstration:

# Normal speed playback
rfswift log replay -i rfswift-exec-mycontainer-20260112-134651.cast

# 2x speed playback (useful for long sessions)
rfswift log replay -i session.cast -s 2.0

# Slow motion for detailed analysis
rfswift log replay -i session.cast -s 0.5

Managing Recordings

List and organize your recorded sessions:

# List recordings in current directory
rfswift log list

# List recordings in specific directory
rfswift log list --dir ~/recordings

# List recordings from assessment project
rfswift log list --dir /projects/client-assessment/recordings

Advanced Recording Workflows

Standalone Recording:

For situations where you want to record without immediately entering a container:

# Start recording
rfswift log start -o my-session.cast

# ... perform your work ...

# Stop recording
rfswift log stop

5. Device and Resource Management

Audio Support

RF Swift will warn if audio support is not properly configured:

┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ⚠️  Warning                                                                                       │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Warning: Unable to connect to Pulse server at 127.0.0.1:34567                                    │
...
└──────────────────────────────────────────────────────────────────────────────────────────────────┘

Enable audio support (run without sudo):

rfswift host audio enable
[+] Successfully loaded module-native-protocol-tcp with index 29

Dynamic Device and Volume Binding

One of RF Swift’s most powerful features is the ability to add or remove device bindings to running containers:

# Add a USB device to an existing container
rfswift bindings add -c my_container -d -s /dev/ttyUSB0:/dev/ttyUSB0

# For some destination, use shortcuts with -t only
rfswift bindings add -c my_container -d -t /dev/ttyUSB0

# Add a shared folder
rfswift bindings add -c my_container -b ~/projects:/root/projects

# Remove a binding
rfswift bindings rm -c my_container -t /dev/ttyUSB0 [-d]

# List current bindings
rfswift bindings list -c my_container

Don’t forget the -d switch if you want to deal with devices and not volumes.

Realtime Mode for SDR Performance

If you experience buffer underruns or dropped samples with your SDR hardware, enable realtime mode:

# Enable on existing container
rfswift realtime enable -c my_sdr_container

# Check current status
rfswift realtime status -c my_sdr_container

# Disable if no longer needed
rfswift realtime disable -c my_sdr_container

Realtime mode configures:

  • rtprio=95 ulimit for real-time scheduling
  • memlock=unlimited to prevent buffer swapping
  • SYS_NICE capability for priority control

Once enabled, you can use real-time scheduling inside the container:

# Run SDR tool with real-time priority
chrt -f 50 rtl_sdr -f 433920000 -s 2048000 output.bin

# Verify rtprio is set
ulimit -r  # Should show 95
For fine-grained control, use rfswift ulimits to manage individual resource limits. See the ulimits documentation for details.

6. Network Configuration

RF Swift supports various network isolation modes:

Mode Description
host No network isolation (default)
bridge Default Docker network driver with isolation
none Complete network isolation
overlay Connect multiple Docker daemons
ipvlan Full IPv4/IPv6 addressing control
macvlan Assign MAC addresses to containers

Example of using bridge mode with port mapping:

rfswift run -i bluetooth -n my_container -t bridge -z 8000 -w 8000:127.0.0.1:80/tcp

This command:

  • Uses the -t bridge option to enable bridge networking
  • Maps container port 8000 to host port 80 on localhost with -w 8000:127.0.0.1:80/tcp
  • Exposes port 8000 to other containers with -z 8000
For Wi-Fi and Bluetooth tools, you may need to add the NET_ADMIN capability: rfswift run -i wifi_tools -n my_container -a NET_ADMIN Be cautious when adding capabilities as they increase security risks if the container is compromised.

Container Architecture Benefits

  graph TD;
    A[Core build]-->B[Image 1];
    A-->C[Docker image 2];
    B-->D[Container #1 from image 1];
    B-->E[Container #2 from image 1];
    C-->F[Container from image 2]

This architecture provides significant advantages:

  • Portability: Move environments between systems easily
  • Isolation: Create separate environments for different tasks
  • Disposability: Create, experiment with, and destroy environments without impact
  • Specialization: Tailored environments for specific assessment needs
  • Efficiency: No need to reinstall entire systems
  • Performance: Less resource-intensive than VMs
  • Time-saving: Quick deployment for last-minute assessment preparations
  • Documentation: Built-in session recording for compliance and reporting
RF Swift significantly flattens the Docker learning curve while providing powerful features like dynamic device binding, host resource integration, and session recording that would otherwise require considerable Docker expertise.

Using RF Tools

Once your container is running, you can use any included RF tools. For example, with an SDR device connected:

┌─[root@topms] - [~] - [Tue Sep 03, 15:15]
└─[$]> sdrangel

Running SDRAngel with an RTL-SDR
Running SDRAngel with an RTL-SDR

GUI applications require:

  • Linux: xhost installed and configured
  • macOS: XQuartz properly configured
  • Windows: Native support via Docker Desktop
SDR Performance Tip: If you experience buffer underruns or dropped samples, create your container with the --realtime flag or enable it afterwards with rfswift realtime enable -c container_name. See the realtime documentation for details.

Advanced Features

Host Isolation

RF Swift implements host isolation through several security mechanisms configured in your config.ini file:

[container]
privileged = false
caps =
seccomp =
cgroups = c 189:* rwm,c 166:* rwm,c 188:* rwm

Default Security Configuration

By default, RF Swift runs containers in unprivileged mode with specific cgroup restrictions:

  • Unprivileged Mode: Containers run without full root privileges on the host (privileged = false)
  • Cgroup Restrictions: Controlled device access through character device major numbers:
    • c 189:* rwm: Access to USB serial devices (ttyUSB*)
    • c 166:* rwm: Access to ACM devices (ttyACM*)
    • c 188:* rwm: Access to USB serial converters

This provides a reasonable balance between functionality and security for RF applications.

Customizing Security Settings

You can customize security settings both in the config file and via command-line parameters:

Adding Capabilities:

# Via command line
rfswift run -i sdr_full -n my_container -a NET_ADMIN,SYS_PTRACE

# Via config.ini
caps = NET_ADMIN,SYS_PTRACE

Custom Seccomp Profile:

# Via command line
rfswift run -i sdr_full -n my_container -m /path/to/seccomp.json

# Via config.ini
seccomp = /path/to/seccomp.json

Additional Cgroup Rules:

# Via command line
rfswift run -i sdr_full -n my_container -g "c 226:* rwm"

# Via config.ini
cgroups = c 189:* rwm,c 166:* rwm,c 188:* rwm,c 226:* rwm

Cgroup rules use the format type major:minor permission where:

  • type is c (character) or b (block)
  • major:minor defines the device number (use * for wildcard)
  • permission is r (read), w (write), m (mknod)

For example, c 189:* rwm grants full access to all devices with major number 189.

Command-Line Security Configuration

RF Swift allows you to override or extend security settings directly from the command line when running containers. This is particularly useful for one-off tasks or testing configurations before adding them to your config file.

Complete List of Security-Related Flags:

rfswift run [options]

Security Options:
  -u, --privileged int        Set privilege level (1: privileged, 0: unprivileged)
  -a, --capabilities string   Extra capabilities (separate with commas)
  -g, --cgroups string        Extra cgroup rules (separate with commas)
  -m, --seccomp string        Set Seccomp profile ('default' one used by default)
  -s, --devices string        Extra devices mapping (separate with commas)
  
Network Options:  
  -t, --network string        Network mode (default: 'host')
  -z, --exposedports string   Exposed ports
  -w, --bindedports string    Ports to bind between host and container
  -x, --extrahosts string     Set extra hosts (default: 'pluto.local:192.168.1.2')
  
Resource Options:
  -b, --bind string           Extra volume bindings (separate with commas)
  -d, --display string        Set X Display (default "DISPLAY=:0")
  -p, --pulseserver string    PULSE SERVER TCP address (default "tcp:127.0.0.1:34567")

Performance Options:
  --realtime                  Enable realtime mode (SYS_NICE + rtprio + memlock)
  --ulimits string            Set custom ulimits (e.g., 'rtprio=95,memlock=-1')

Recording Options:
  --record                    Record the container session
  --record-output string      Custom output filename for recording (default: auto-generated)
  
Display Options:
  --no-x11                    Disable X11 forwarding

Examples of Command-Line Security Configurations:

  1. Run with specific privileges and capabilities:

    rfswift run -i penthertz/rfswift_noble:wifi -n wifi_tools -u 0 -a NET_ADMIN,NET_RAW

    This runs a container in unprivileged mode but adds the NET_ADMIN and NET_RAW capabilities.

  2. Add custom cgroup rules and device mappings:

    rfswift run -i penthertz/rfswift_noble:sdr -n rtlsdr -g "c 226:* rwm" -s "/dev/bus/usb:/dev/bus/usb"

    This adds permission for device major number 226 and maps a specific RTL-SDR device.

  3. Set a custom seccomp profile:

    rfswift run -i penthertz/rfswift_noble:security -n forensics -m ~/custom_seccomp.json

    This applies a custom seccomp profile to the container.

  4. High-performance SDR setup with realtime mode:

    rfswift run -i penthertz/rfswift_noble:sdr_full -n sdr_capture \
      --realtime \
      -s "/dev/bus/usb:/dev/bus/usb" \
      -g "c 189:* rwm" \
      -b ~/captures:/root/captures \
      --record

    This creates a container with:

    • Realtime mode for optimal SDR performance
    • USB device access
    • Cgroup rules for USB serial devices
    • Shared captures folder
    • Session recording enabled
  5. Combined security settings with recording:

    rfswift run -i penthertz/rfswift_noble:bluetooth -n bt_scanner \
      -t bridge \
      -a NET_ADMIN \
      -g "c 226:* rwm,c 116:* rwm" \
      -s "/dev/bluetooth:/dev/bluetooth" \
      -u 0 \
      --record --record-output bluetooth-assessment.cast

    This creates a container with:

    • Bridge networking mode
    • NET_ADMIN capability
    • Custom cgroup rules for devices with major numbers 226 and 116
    • Specific Bluetooth device mapping
    • Unprivileged mode
    • Session recording enabled
Command-line settings always take precedence over config file settings. When using both, command-line options will extend or override the corresponding settings in your config.ini file.

Next Steps

Now you can dive right into:

Last updated on