nerdymark's Software Engineering & Cybersecurity Blog

Welcome to my digital homestead - a curated collection of projects, writeups, and experiments in Python, cybersecurity, and creative coding.

Here you'll find CTF writeups covering Azure OAuth privilege escalation, AWS S3 multi-service exploitation, Kubernetes SSRF attack chains, Terraform state poisoning, Go malware reverse engineering, and supply-chain compromises on GitHub Actions runners. You'll also find side projects like the Pokemon Sleep Roster Analyzer, an RDP/VNC network scanner, a LinkedIn feed analyzer powered by Gemini, and word-puzzle solvers for Wordle and Hardle. Plus notes on building this Flask site, migrating to AWS, Bluesky cross-posting, and running a personal AI robot out of my garage.

I'm Mark LaCore - Software Engineer by day, Raspberry Pi tinkerer by night. 25 years of turning caffeine into code, 20+ years of playing guitar, and a growing collection of CTF trophies. Explore the posts below, browse the CTF writeups, or drop me a line.

Track a sanitized auto_rx station config auto_rx/station.cfg.example is a synce...

File: .gitignore
 data/
 # --- local station config & personal exports (contain credentials / personal data) ---
 # auto_rx/station.cfg is the live radiosonde_auto_rx source config (api/autorx.py
-# regenerates the runtime cfg from it); it holds the Bluesky app password.
-auto_rx/
+# regenerates the runtime cfg from it); it holds the Bluesky app password and the
+# exact station coordinates. The sanitized auto_rx/station.cfg.example IS tracked.
+auto_rx/station.cfg
 *.csv
 # --- editor / tooling ---
File: auto_rx/station.cfg.example
+# ------------------------------------------------------------------------------
+# nerdscan station config for radiosonde_auto_rx (SANITIZED TRACKED COPY)
+#
+# This is a synced copy of the untracked auto_rx/station.cfg (the live source
+# config that api/autorx.py regenerates the runtime cfg from), with secrets
+# redacted so the station settings survive in git:
+#   - web_password / bluesky app_password  -> CHANGEME
+#   - station_lat/lon                      -> rounded to ~1 km
+# To restore: copy to auto_rx/station.cfg and fill in the CHANGEME values and
+# exact station coordinates. Keep this file in sync when settings change.
+# ------------------------------------------------------------------------------
+#
+# Radiosonde Auto RX v2 Station Configuration File
+#
+# Copy this file to station.cfg and modify as required.
+#
+# If you only change a few settings, the important ones to change are:
+# - [habitat] -> uploader_callsign - Your station callsign!
+# - [location] -> station_lat, station_lon, station_alt - Your station location!
+# - [search_params] -> min_freq, max_freq - Set these suitable for your location!
+#
+
+################
+# SDR SETTINGS #
+################
+[sdr]
+
+#
+# SDR Type
+#
+# RTLSDR - Use one or more RTLSDRs
+#
+# Network SDR Server options:
+# SpyServer - Use an Airspy SpyServer
+# KA9Q - Use a KA9Q-Radio Server
+#
+sdr_type = RTLSDR
+
+
+#
+# Number of SDRs or SDR Connection Threads to use
+#
+# If SDR type is set to RTLSDR above, then this number is the number of individual RTLSDRs
+# that will be used, eith each RTLSDR allocated a scan or decode task.
+# If more than one RTLSDR is in use, multiple [sdr_X] sections must be populated below
+#
+# If SDR type is either KA9Q or SpyServer, this defines the maximum number of parallel
+# decoding/scan tasks. On a RPi 4, ~5 tasks are possible.
+#
+sdr_quantity = 1
+
+
+#
+# Network SDR Connection Details
+#
+# If using a spyserver, the hostname and port need to be defined below.
+# Is using KA9Q-Radio, the hostname of the 'radio' server (e.g. sonde.local) needs to be
+# defined, and the port number is unused.
+#
+sdr_hostname = localhost
+sdr_port = 5555
+
+#
+# Individual RTLSDR Settings
+#
+# Provide details of your RTLSDRs here, e.g. device numbers, gain settings, and PPM offsets.
+# If using a Network SDR, do not modify any of these settings.
+#
+[sdr_1]
+# Device Index / Serial
+#	If using a single RTLSDR, set this value to 0
+#	If using multiple SDRs, you MUST allocate each SDR a unique serial number using rtl_eeprom
+#   The serial number must NOT be 00000000 or 00000001, as this causes big confusion to the rtl utilities.
+#	i.e. to set the serial number of a (single) connected RTLSDR: rtl_eeprom -s 00000002
+#	Then set the device_idx below to 00000002, and repeat for the other [sdr_n] sections below
+#
+#   For the special case when auto_rx is used entirely with a JSON-via-UDP input, set the below to TCP001
+#   This will bypass all RTLSDR checks and allow auto_rx to continue running.
+device_idx = 00000181
+
+# Frequency Correction (ppm offset)
+# 	Refer here for a method of determining this correction using LTE signals: https://gist.github.com/darksidelemm/b517e6a9b821c50c170f1b9b7d65b824
+# NOTE: nerdscan regenerates the [sdr_N] blocks at runtime from
+# api/autorx.PPM_BY_SERIAL, so this value is NOT what actually runs — it's just
+# the base-file default. Per-dongle measured ppms live in PPM_BY_SERIAL.
+# (The E4000 35257786 measured ~-2 ppm on 2026-06-28; an earlier ~-25 reading
+# against a weak NWR signal was wrong.)
+ppm = -2
+
+# SDR Gain Setting
+#   Gain settings can generally range between 0dB and 40dB depending on the tuner in use.
+#   Run rtl_test to confirm what gain settings are available, or use a value of -1 to use hardware automatic gain control (AGC).
+#   Note that this is an overall gain value, not an individual mixer/tuner gain. This is a limitation of the rtl_power/rtl_fm utils.
+gain = -1
+
+# Bias Tee - Enable the bias tee in the RTLSDR v3 Dongles.
+bias = False
+
+[sdr_2]
+# As above, for the next SDR, if used. Note the warning about serial numbers.
+device_idx = 00000002
+ppm = 0
+gain = -1
+bias = False
+
+# Add more SDR definitions here if needed. ([sdr_3], [sdr_4])
+
+
+##############################
+# RADIOSONDE SEARCH SETTINGS #
+##############################
+[search_params]
+# Minimum and maximum search frequencies, in MHz.
+# Australia: Use 400.05 - 403 MHz
+# New Zealand: Use 400.05 - 404 MHz
+# Europe: Use 400.05 - 406 MHz
+# US:
+#   Some areas have transitioned to the 400.05 - 406 MHz band, so try 400.05 - 406
+#   Some areas are still using ~1680 MHz sondes, which use channels of 1676, 1678, 1680 and 1682 MHz (Thanks Tory!)
+#   Example only_scan for these sondes: [1676.0, 1678.0, 1680.0, 1682.0]
+#   In these areas I suggest using the only_scan feature below instead of using the peak-detect search.
+#	You may also need to apply a small offset to the frequency for decoding reliability (i.e. 1676.025 MHz) as
+#	the sondes are often off-frequency. For now, check in something like GQRX to get an idea of what offset is required.
+#
+# Note - when using either a KA9Q or SpyServer as the SDR backend, the frequency scan limits are set by the
+# Server.
+
+min_freq = 400.05
+max_freq = 406.0
+
+# After rx_timeout seconds of no valid data from a decoder, stop the decoder and go back to scanning (if a SDR is available)
+rx_timeout = 300
+
+# Frequency Lists - These must be provided as JSON-compatible lists of floats (in MHz), i.e. [400.50, 401.520, 403.200]
+
+# only_scan - Add values to this list to *only* scan on these frequencies.
+# This is for when you only want to monitor a small set of launch frequencies.
+only_scan = []
+
+# never_scan - Any values added to this list will be removed from the list of detected peaks.
+# This is used to remove known spurs or other interferers from the scan list, potentially speeding up detection of a sonde.
+# Persistent local spurs (2026-07-10 survey: ~700 failed detection attempts in
+# 2 h). Entries block +/-quantization/2 (500 Hz), so clusters are tiled at 1 kHz.
+# Centers: 401.042 402.042 402.852 403.026 403.122 403.198 404.976 405.007
+# The 403.026 cluster is trimmed to 403.023-403.028 so the 403.02/403.03 sonde
+# grid channels stay scannable (DFM17 25032301 flew at 403.010 on 2026-07-13,
+# one channel below the old cluster edge). A rare spur leak-through costs one
+# ~12 s dwell and self-limits via the 60 min temporary block.
+never_scan = [401.031, 401.032, 401.033, 401.034, 401.035, 401.036, 401.037, 401.038, 401.039, 401.04, 401.041, 401.042, 401.043, 401.044, 401.045, 401.046, 401.047, 401.048, 401.049, 401.05, 401.051, 402.04, 402.041, 402.042, 402.043, 402.044, 402.85, 402.851, 402.852, 402.853, 402.854, 403.023, 403.024, 403.025, 403.026, 403.027, 403.028, 403.029, 403.03, 403.031, 403.032, 403.033, 403.034, 403.119, 403.12, 403.121, 403.122, 403.123, 403.124, 403.19, 403.191, 403.192, 403.193, 403.194, 403.195, 403.196, 403.197, 403.198, 403.199, 403.2, 403.201, 403.202, 403.203, 403.204, 403.205, 403.206, 404.975, 404.976, 404.977, 404.978, 405.004, 405.005, 405.006, 405.007, 405.008, 405.009, 405.01, 405.011, 405.012, 405.013, 405.014]
+
+# always_scan - Any values in this list will be added to the start every scan run.
+# This is useful when you know the regular frequency of a local sonde, but still want to allow detections on other frequencies.
+# Local launch channels actually observed here (always_scan bypasses BOTH
+# never_scan and the peak threshold, so these get a detect dwell every pass —
+# catches a sonde before it clears the horizon/threshold):
+#   403.01 — DFM17 (25032301, 2026-07-13)
+#   404.0  — RS41 (X4666319 @ 403.999, 2026-06-28)
+# Cost: ~12 s per entry per scan pass.
+always_scan = [403.01, 404.0]
+
+# always_decode - Always-running decoders. Only possible in a multi-SDR (or network-based SDR) system.
+# List must be in the form: [[401.5,"RS41"], [402.5,"DFM"], [400.5,"M10"], [400.5,"IMET"]]
+# Valid sonde types: RS41, RS92, DFM, M10, M20, IMET, IMETWIDE, IMET5, MK2LMS, LMS6, MEISEI, MRZ, MTS01
+always_decode = []
+
+
+####################
+# STATION LOCATION #
+####################
+# Used by the Sondehub Uploader, APRS Uploader, and by Rotator Control
+# Lat/Lon in decimal degrees, altitude in metres (AMSL).
+# Note: You do not need to specify your home station accurately if you don't want to!
+# Feel free to use a position somewhere near your general area, that doesn't identify your home location.
+#
+# If this is a mobile or portable station, it is recommended to leave this at 0.0, and disable
+# 'upload_listener_position' in the section below. Mobile station positions should be uploaded using
+# ChaseMapper.
+[location]
+station_lat = 37.32
+station_lon = -121.89
+station_alt = 30.0
+
+# Station Position from GPSD
+# If your station is likely to move, then you may wish to have your station position updated from GPSD.
+# NOTE: This feature is intended to make life slightly easier when using an auto_rx station in a portable
+# capacity, in particular when using a rotator. It is *not* intended for uploading positions of mobile
+# chase-cars.
+# For the web interface to start up correctly, a lat/lon still needs to be entered above.
+# If you are operating a stationary auto_rx station, please just set a fixed position above rather than using GPSD.
+#
+# If you are doing mobile balloon chasing, please use chasemapper ( https://github.com/projecthorus/chasemapper )
+# which is far beter suited than auto_rx by itself...
+gpsd_enabled = False
+gpsd_host = localhost
+gpsd_port = 2947
+
+
+###################################################
+# SONDEHUB / HABITAT (deprecated) UPLOAD SETTINGS #
+###################################################
+#
+# Settings relating to uploads to the SondeHub v2 Database and tracker,
+# available at https://tracker.sondehub.org/
+#
+# Note that uploads to the Habitat (amateur HAB) database are now disabled,
+# and any references to Habitat in this config are for legacy reasons only.
+[habitat]
+
+# Uploader callsign. PLEASE CHANGE THIS TO SOMETHING UNIQUE.
+# If using ChaseMapper to upload mobile station positions, ensure this callsign
+# is set identically to that set in ChaseMapper.
+uploader_callsign = KO6ODW-S
+
+# Upload listener position to Sondehub? (So you show up on the map)
+# Note that if GPSD is used, this is overriden and enabled.
+# If this is a mobile or portable station, it is recommended to set this to False.
+# Mobile stations should use ChaseMapper or the SondeHub Tracker to upload positions.
+upload_listener_position = True
+
+# Uploader Antenna Description.
+# If upload_listener_position is enabled, this information will show up in your station description on the habhub map.
+uploader_antenna = Tactical whip with ground plane
+
+[sondehub]
+# Enable uploading to Sondehub v2 - please leave this enabled!
+sondehub_enabled = True
+
+# How often to push data to the SondeHub Database. (seconds)
+# All received positions are cached and uploaded every X seconds.
+# Uploads are gzip compressed, so don't require much data transfer.
+# Users receiving Graw DFM sondes may want to set this to 30 to improve
+# the chances of uploads not being rejected by our Z-check.
+# (Refer: https://github.com/projecthorus/sondehub-infra/wiki/DFM-radiosonde-above-1000-and-not-enough-data-to-perform-z-check )
+sondehub_upload_rate = 15
+
+# An optional contact e-mail address.
+# This e-mail address will *only* be available to the Sondehub admins, and will *only*
+# be used to contact you if there is an obvious issue with your station.
+# We recommend that you join the radiosonde_auto_rx mailing list to receive updates:
+# https://groups.google.com/forum/#!forum/radiosonde_auto_rx
+sondehub_contact_email = nerdymark@gmail.com
+
+
+
+########################
+# APRS UPLOAD SETTINGS #
+########################
+# Settings for uploading to radiosondy.info
+#
+# IMPORTANT APRS NOTE
+#
+# As of auto_rx version 1.5.10, we are limiting APRS output to only radiosondy.info,
+# and only on the non-forwarding port.
+# This decision was not made lightly, and is a result of the considerable amount of
+# non-amateur traffic that radiosonde flights are causing within the APRS-IS network.
+# Until some form of common format can be agreed to amongst the developers of *all*
+# radiosonde tracking software to enable radiosonde telemetry to be de-duped,
+# I have decided to help reduce the impact on the wider APRS-IS network by restricting
+# the allowed servers and ports.
+# If you are using another APRS-IS server that *does not* forward to the wider APRS-IS
+# network and want it allowed, then please raise an issue at
+# https://github.com/projecthorus/radiosonde_auto_rx/issues
+#
+# You are of course free to fork and modify this codebase as you wish, but please be aware
+# that this goes against the wishes of the radiosonde_auto_rx developers to not be part
+# of the bigger problem of APRS-IS congestion.
+# As of 2022-03-01, radiosonde traffic has been filtered from aprs.fi, so even if you do
+# modify the code, you still won't see sondes on that map.
+# APRS-IS is a *shared resource*, intended for the use of all amateur radio operators, and
+# for many years we have been treating it as a playground to dump large amounts of non-amateur
+# traffic into, so we can see weather balloons on a map.
+# Instead of congesting this shared resource with this non-amateur traffic, we should instead
+# be moving to using databases and sites specialised for this purpose, for example sondehub.org
+
+[aprs]
+# Enable APRS upload (you will also need to change some options below!)
+aprs_enabled = False
+
+# APRS-IS Login Information
+# The aprs_user field can have an SSID on the end if desired, i.e. N0CALL-4
+aprs_user = N0CALL
+# APRS-IS Passcode. You can generate one for your callsign here: https://apps.magicbug.co.uk/passcode/
+aprs_pass = 00000
+
+# APRS Upload Rate - Upload a packet every X seconds.
+# This has a lower limit of 30 seconds, to avoid flooding radiosondy.info
+# Please be respectful, and do not attempt to upload faster than this.
+upload_rate = 30
+
+# APRS-IS server to upload to.
+# Currently we only support uploading to radiosondy.info
+# When using port 14580, packets are not forwarded to the wider APRS-IS network, and hence
+# are help reduce the huge amount of non-amateur traffic that ends up in APRS-IS from
+# radiosondes.
+aprs_server = radiosondy.info
+
+# APRS-IS Port Number to upload to.
+#
+#   Port 14590 - Packets stay within radiosondy.info and do not congest the wider APRS-IS
+#                network.
+#
+aprs_port = 14580
+
+# APRS Station Location Beaconing
+# If enabled, you will show up on APRS using the aprs_user callsign set above.
+# This also requires your station location to be set in the above [location] section.
+station_beacon_enabled = False
+
+# Station beaconing rate, in minutes.
+station_beacon_rate = 30
+
+# Station beacon comment.
+# <version> will be replaced with the current auto_rx version number
+station_beacon_comment = radiosonde_auto_rx SondeGate v<version>
+
+# Station Beacon Icon
+# The APRS icon to use, as defined in http://www.aprs.org/symbols.html
+# Note that the two characters that define the icon need to be concatenated. Examples:
+# Antenna Tower = /r
+# House with Yagi = /y
+# Satellite Dish = /`    (This is required if you want to show up on radiosondy.info's station list.)
+station_beacon_icon = /`
+
+# Custom Object name / Callsign to be used when uploading telemetry to APRS-IS (Max 9 chars)
+# WARNING: THIS SHOULD BE LEFT AT THE DEFAULT OF <id> UNLESS YOU HAVE A VERY GOOD REASON
+# TO CHANGE IT!
+#
+# Using <id> means the uploads from multiple stations remain consistent, and we don't end up with
+# lots of duplicate sondes on APRS-IS. If you enable the station location beaconing (below), maps
+# like aprs.fi and radiosondy.info will show your station as the receiver.
+#
+# If used, this field should be either a callsign with a -11 or -12 suffix (i.e. N0CALL-12),
+# or <id>, which will be replaced with the radiosondes serial number.
+#
+# WARNING - If running multiple RTLSDRs, setting this to a fixed callsign will result in odd behaviour on the online tracker.
+# DO NOT SET THIS TO ANYTHING OTHER THAN <id> IF YOU ARE USING MORE THAN ONE SDR!
+aprs_object_id = <id>
+
+# Confirmation of the above setting.
+# Set to True to confirm use of the custom object ID set above.
+# Please read the notes above before setting this to True.
+aprs_use_custom_object_id = False
+
+# The APRS-IS beacon comment. The following fields can be included:
+# <freq> - Sonde Frequency, e.g. 401.520 MHz
+# <type> - Sonde Type (e.g. RS41-SG, DFM09, etc....)
+# <id> - Sonde Serial Number (i.e. M1234567)
+# <vel_v> - Sonde Vertical Velocity (i.e. -5.1m/s)
+# <temp> - Sonde reported temperature. If no temp data available, this will report -273 degC.
+# <humidity> - Sonde reported humidity.
+# <pressure> - Sonde reported pressure
+# <batt> - Battery Voltage (e.g. 3.1V)
+# The default comment (below) is compatible with radiosondy.info's parsers, and should only be modified
+# if absolutely necessary.
+aprs_custom_comment = Clb=<vel_v> t=<temp> h=<humidity> p=<pressure> <freq> Type=<type> ser=<id> Radiosonde
+
+
+###########################
+# CHASEMAPPER DATA OUTPUT #
+###########################
+# Settings for pushing data into Chasemapper and/or OziPlotter
+# Oziplotter receives data via a basic CSV format, via UDP.
+# Chasemapper can receive data in either the basic CSV format, or in the more descriptive 'payload summary' JSON format.
+[oziplotter]
+# How often to output data (seconds)
+ozi_update_rate = 5
+
+# Enable the 'OziMux' basic CSV output
+# Note - this cannot be enabled in a multi-SDR configuration.
+ozi_enabled = False
+
+# OziMux UDP target host.
+# Defaults to broadcasting
+ozi_host = <broadcast>
+
+# OziMux UDP output port.
+# Set to 8942 to send packets directly into OziPlotter, or set to 55681 to send via OziMux
+ozi_port = 8942
+
+# Payload summary UDP output, which is the preferred input if using ChaseMapper.
+# Using this output allows multiple sondes to be plotted in Chasemapper.
+# As of 2019-05, this is enabled by default.
+payload_summary_enabled = True
+payload_summary_host = <broadcast>
+payload_summary_port = 55673
+
+
+#######################
+# EMAIL NOTIFICATIONS #
+#######################
+# Sends an email notification to the specified address when a new Sonde is detected
+[email]
+email_enabled = False
+
+# Send an e-mail for each new radiosonde observed.
+launch_notifications = True
+
+# Send e-mails when a radiosonde is detected descending near your station location
+landing_notifications = True
+
+# Send e-mails when an encrypted radiosonde is detected.
+encrypted_sonde_notifications = True
+
+# Range threshold for Landing notifications (km from your station location)
+landing_range_threshold = 30
+
+# Altitude threshold for Landing Notifications (metres)
+# Notifications will only occur for sondes which have been observed descending (>2m/s descent rate) below this altitude
+# for at least 10 observations
+landing_altitude_threshold = 1000
+
+# Enable sending critical error notifications (one that cause auto_rx to completely crash out) via email.
+# WARNING: If an error is persistent and you are running as a systemd service, this could result
+# in many e-mails being sent!
+error_notifications = False
+
+# Server details. Note that usually Port 465 is used for SSL auth, and 587 is used for TLS.
+smtp_server = localhost
+smtp_port = 25
+
+# Authentication type, Valid options are: None, TLS, and SSL
+smtp_authentication = None
+
+# If using authentication, the following fields need to be populated:
+smtp_login = None
+smtp_password = None
+
+# 'Source' e-mail
+from = sonde@localhost
+
+# Destination emails. You can send to multiple addresses by separating each address with a semicolon,
+# i.e.   test@test.com;test2@test2.com
+to = someone@example.com
+
+# Custom subject field. The following fields can be included:
+# <freq> - Sonde Frequency, i.e. 401.520 MHz
+# <type> - Sonde Type (RS94/RS41)
+# <id> - Sonde Serial Number (i.e. M1234567)
+subject = <type> Sonde launch detected on <freq>: <id>
+
+# Custom nearby landing subject field. The following fields can be included:
+# <freq> - Sonde Frequency, i.e. 401.520 MHz
+# <type> - Sonde Type (RS94/RS41)
+# <id> - Sonde Serial Number (i.e. M1234567)
+nearby_landing_subject = Nearby Radiosonde Landing Detected - <id>
+
+
+###################
+# ROTATOR CONTROL #
+###################
+#   auto_rx can communicate with an instance of rotctld, on either the local machine or elsewhere on the network.
+#   This is, admittedly, a bit of a waste of an az/el rotator setup when a vertical antenna usually works fine,
+#   but it's still fun :-)
+[rotator]
+# WARNING - This should not be enabled in a multi-SDR configuration.
+# Your station location (defined in the [location] section above) must also be defined.
+rotator_enabled = False
+# How often to update the rotator position. (Seconds)
+update_rate = 30
+# Only move the rotator if the new position is more than X degrees in azimuth or elevation from the current position.
+rotation_threshold = 5.0
+# Hostname / Port of the rotctld instance.
+rotator_hostname = 127.0.0.1
+rotator_port = 4533
+# Rotator Homing.
+# If enabled, turn to a 'home' location when scanning for sondes.
+# This could be used to point an antenna at a known radiosonde launch location.
+rotator_homing_enabled = False
+# Wait until x minutes after no sonde data received before moving to the home location.
+rotator_homing_delay = 10
+# Rotator home azimuth/elevation, in degrees true.
+rotator_home_azimuth = 0.0
+rotator_home_elevation = 0.0
+# Azimuth-only rotator - set this to True if your rotator only moves in Azimuth
+# This will force all elevation settings to 0
+azimuth_only = False
+
+
+###########
+# LOGGING #
+###########
+[logging]
+# If enabled, a log file will be written to ./log/ for each detected radiosonde.
+per_sonde_log = True
+
+# Enable logging of system-level logs to disk.
+# This is the equivalent of starting auto_rx with the --systemlog option, but only takes effect after the config file is read.
+# These logs will end up in the log directory.
+save_system_log = False
+
+# Enable logging of debug messages.
+# This is the equivalent of starting auto_rx with the -v option, but only takes effect after the config file is read.
+# This setting, in combination with save_system_log (above), can help provide detailed information when debugging
+# auto_rx operational issues.
+enable_debug_logging = False
+
+# Enable logging of RS41 Calibration data ('subframe' data)
+# This is saved as a binary file with file suffix _subframe.bin
+save_cal_data = False
+
+###########################
+# WEB INTERFACE SETTINNGS #
+###########################
+[web]
+# Server Host - Can be set to :: to listen on IPv6
+# Leave this at 0.0.0.0 to have the web server listen on all interfaces.
+web_host = 0.0.0.0
+# Server Port - Ports below 1024 can only be used if you run auto_rx as root (not recommended)
+web_port = 5000
+# Archive Age - How long to keep a sonde telemetry in memory for the web client to access, in minutes
+# Note: The higher this number, the more data the client will need to load in on startup
+archive_age = 120
+
+# Enable control over the scanner, and starting/stopping decoders from the web interface.
+# A password must also be set (below).
+# USERS ENABLE THIS AT THEIR OWN RISK!!
+web_control = True
+
+# Password for controls on the web interface. The main interface will still be publicly available.
+# Note that as the web interface is HTTP-only, this password will be sent over the internet in the clear,
+# so don't re-use passwords!
+web_password = CHANGEME
+
+# KML refresh rate
+kml_refresh_rate = 10
+
+
+##################
+# DEBUG SETTINGS #
+##################
+[debugging]
+# WARNING - Enabling these settings can result in lots of SD-card IO, potentially
+# reducing the life of the card. These should only be enabled to collect data for
+# debugging purposes.
+
+# Save the audio that a detection pass is run over to: detect_<SDR_ID>.wav
+# This file is over-written with every new detection.
+save_detection_audio = False
+
+# Save the audio from the output from a sonde decode chain to decode_<SDR_ID>.wav
+# This file is over-written with each new sonde decoded for a particular SDR.
+# This only works for the 'legacy' FM-based demodulators.
+save_decode_audio = False
+
+# Save the decimated IQ data from an experimental sonde decode chain to decode_IQ_<SDR_ID>.bin
+# This will be in complex signed 16-bit int format, and may be either 48 kHz or 96 kHz.
+# Note: This will use a LOT of disk space.
+save_decode_iq = False
+
+# Save raw hexadecimal radiosonde frame data. This is useful to provide data for telemetry analysis.
+# Raw hex data is saved to the logging directory with a filename of format YYYYMMDD-HHMMSS_<type>_<freq>.raw
+# Saving raw data is currently only supported for: RS41, LMS6-1680, LMS6-400, M10, M20, IMET-4
+save_raw_hex = False
+
+
+#####################
+# ADVANCED SETTINGS #
+#####################
+# These control low-level settings within various modules.
+# Playing with them may result in odd behaviour.
+[advanced]
+# Scanner - Receive bin width (Hz)
+search_step = 800
+# Scanner - Minimum SNR for a peak to be detected. The lower the number, the more peaks detected.
+snr_threshold = 3
+# Scanner - Maximum number of peaks to search through during a scan pass.
+#	Increase this if you have lots of spurious signals, though this will increase scan times.
+max_peaks = 10
+# Scanner - Minimum distance between detected peaks (Hz)
+min_distance = 1000
+# Scanner - Scan Dwell Time - How long to observe the specified spectrum for.
+# (Lowered from the 20 s default 2026-07-23 for a faster-updating scan plot;
+#  10 s integration is still plenty of averaging for our 3 dB snr_threshold.)
+scan_dwell_time = 10
+# Scanner - Detection Dwell time - How long to wait for a sonde detection on each peak.
+# (Back to the upstream default 2026-07-23: dft_detect exits EARLY when it finds
+#  a sonde, so a long dwell mostly slows down REJECTING noise peaks — each spur
+#  cost ~12 s at dwell 10 and stalls the next scan sweep. Real sondes correlate
+#  in a few seconds.)
+detect_dwell_time = 5
+# Scanner - Delay between scans. We should delay a short amount between scans to allow for decoders and other actions to jump in.
+# (Lowered from 10 s alongside scan_dwell_time; ~15-20 s per scan cycle total.)
+scan_delay = 5
+# Quantize search results to x Hz steps. Useful as most sondes are on 10 kHz frequency steps.
+quantization = 1000
+# Decoder Spacing Limit - Only start a new decoder if it is separated from an existing decoder by at least
+# this value (Hz). This helps avoid issues where a drifting radiosonde is detected on two adjacent channels.
+# If you regularly encounter radiosondes on adjacent (10kHz) channels, then set this value to 5000.
+decoder_spacing_limit = 15000
+# Temporary Block Time (minutes) - How long to block encrypted or otherwise non-decodable sondes for.
+temporary_block_time = 120
+# Auto-block persistently failing peaks (nerdscan fork, 2026-07-23) - block a ~10 kHz chunk for
+# auto_block_time minutes after auto_block_after consecutive failed detects in it. Keeps the drifting
+# birdies around 403.02 / 405.01 / 404.99 / 405.49 from eating a detect dwell on every scan pass.
+# always_scan freqs are exempt; a successful detection clears the count.
+auto_block_after = 3
+auto_block_time = 30
+# Abandon burst sondes (nerdscan fork, 2026-07-24): 2 min after burst is confirmed, drop the
+# descending sonde, block its freq for burst_block_time and re-scan — Edwards/Vandenberg sondes
+# can still be floating while we ride a dead one down. Blocked freq can be re-acquired after TTL.
+abandon_after_burst = 120
+burst_block_time = 30
+# Maximum Async Scan Workers - When using KA9Q-radio, how many concurrent detection tasks to run.
+# This only applies when sdr_type = KA9Q. Ignored for RTLSDRs (which scan sequentially).
+# Valid range: 1-32. Automatically capped at CPU core count. Default is 4 (conservative).
+max_async_scan_workers = 4
+# Upload when (seconds_since_utc_epoch%upload_rate) == 0. Otherwise just delay upload_rate seconds between uploads.
+# Setting this to True with multple uploaders should give a higher chance of all uploaders uploading the same frame,
+# however the upload_rate should not be set too low, else there may be a chance of missing upload slots.
+synchronous_upload = True
+# Only accept a payload ID as valid until it has been seen N times.
+# This helps avoid corrupted callsigns getting onto the map.
+payload_id_valid = 3
+# Paths to the rtl_fm and rtl_power utilities. If these are on your system path, then you don't need to change these.
+sdr_fm_path = rtl_fm
+sdr_power_path = rtl_power
+
+# Paths to SpyServer client (https://github.com/miweber67/spyserver_client) utilities, for experimental SpyServer Client support
+# At the moment we assume these are in the auto_rx directory.
+ss_iq_path = ./ss_iq
+ss_power_path = ./ss_power
+
+
+################################
+# DEMODULATOR / DECODER TWEAKS #
+################################
+
+#
+# Alternate Decode Chains
+#
+# NOTE: This section will be deprecated soon, with the fsk_demod chains used permanently.
+#
+# These (not so) experimental demod chains use David Rowe's fsk_demod modem.
+# They have much better drift handling performance, and so may be better suited for
+# 1680 MHz sondes, but use considerably more CPU. Recommend use of a Pi 3 or better.
+# The experimental decoders can be enabled/disabled independently for each radiosonde type.
+# It is recommended that these are always left enabled.
+rs41_experimental = True
+rs92_experimental = True
+dfm_experimental = True
+m10_experimental = True
+lms6-400_experimental = True
+imet54_experimental = True
+meisei_experimental = True
+
+# LMS6-1680 Decoder options:
+# False = Less CPU, possibly worse weak-signal performance.
+# True = Higher CPU (Pushing a RPi 3 to its limits), possibly better weak-signal performance.
+lms6-1680_experimental = False
+
+# MRZ sondes have not yet been tested with the fsk_demod flowgraph in the wild.
+# If someone can confirm that this works, I'll set it to True by default!
+mrz_experimental = False
+
+# Note: As iMet-4 sondes use AFSK, using fsk_demod does not give any advantage, so there is no experimental decoder for them.
+
+# Optimize 1680 MHz Scanning for RS92-NGP Sondes
+# This flag sets the use of IQ detection when scanning for 1680 MHz sondes, which allows RS92-NGP sondes
+# to be detected reliably.
+# Set this to True if you are sure that only RS92-NGPs are flying in your area.
+ngp_tweak = False
+
+# Wideband Radiosonde Detection:
+# Enables some tweaks to better handle detection and decoding of the following radiosonde types:
+# - Intermet iMet-1/4 (Wideband versions)
+# - Weathex WxR-301d
+# If this is enabled in areas with 'narrowband' sondes as well (RS41, DFM, narrowband iMet, etc...) there will likely
+# be degradation in detection and decode performance.
+wideband_sondes = False
+
+# Encrypted RS41-SGM handling:
+# When an encrypted RS41-SGM is detected:
+# True - auto_rx will close the decoder and lock-out the frequency for `temporary_block_time` minutes.
+# False - auto_rx will continue decoding this sonde, including writing a log file, but will not upload telemetry anywhere.
+# The default for this is True, as it can tie up SDRs un-necessarily. Not as big of an issue for a KA9Q-radio station.
+close_on_encrypted = True
+
+######################
+# POSITION FILTERING #
+######################
+#   These are used to discard positions which are clearly bad, such as where the payload has jumped halfway around the world,
+#   or has suddenly ended up in orbit.
+#
+#   Users can also decide to temporary block sondes which are outside of a radius range.
+#
+[filtering]
+# Discard positions with an altitude greater than 50000 metres.
+max_altitude = 50000
+
+# Discard positions from sondes which are outside the following min/max radius limits.
+# This requires the ground-station location to be set.
+max_radius_km = 1000
+min_radius_km = 0
+
+# Temporarily block the frequency of sondes which report a position outside of the above limits.
+# WARNING: This may cause sondes which sometimes report glitchy positions (RS92, DFM) to be blocked.
+# (True or False)
+radius_temporary_block = False
+
+# Reported Time Threshold
+# Discard positions if the sonde's reported time is more than X hours from the system time.
+# This helps catch glitches around 00Z UTC from iMet & LMS6 sondes, and bad CRC checks from
+# DFM sondes.
+sonde_time_threshold = 3
+
+# Whether to perform real-time velocity filtering
+# This filter calculates the velocity between the previous decoded telemetry frame and
+# newly received frames, and discards them if it is faster than the velocity configured below.
+# This helps discard the frame with invalid GPS data that DFM sondes transmit once per flight.
+enable_realtime_filter = True
+
+# Maximum velocity in metres per second for sondes to be discarded in the real-time filter
+max_velocity = 300
+
+
+#########################################
+# BLUESKY NOTIFICATIONS (nerdscan fork) #
+#########################################
+[bluesky]
+enabled = True
+handle = nerdymark.com
+app_password = CHANGEME
+pds_url = https://bsky.social
+discovery_notifications = True
+burst_notifications = True
+burst_altitude_threshold = 5000
+
+[caw]
+enabled = True
+url = https://nerdymark.com/api/caw
+discovery_notifications = True
+burst_notifications = True
+lost_contact_notifications = True
+lost_contact_minutes = 15
+burst_altitude_threshold = 5000
Read more...