Sign inSign up

x3rax/udp-hello

By x3rax

Updated over 6 years ago

Image
0

1.1K

x3rax/udp-hello repository overview

UDP Hello

"UDP Hello" is a simple udp ping responder. It waits for a specific token in the data section of a UDP datagram and sends an answer back to the origin address.

This can be used to verify that a host is up or to check if a device is connected to the internet (or at least to a network that is connected to the UDP Hello server).

The token ensures that the port appears to be not used (filtered) as a response will only be sent when the token is correct. As UDP is connectionnless it will be harder to tell the open port apart from a port that simply drops all incoming datagrams by a firewall rule.

How to use

Start the Server

By default, the server listens on 127.0.0.1 and chooses a random port. In order to make the server listen on all interfaces, you need to tell it to listen on 0.0.0.0 (or whatever IP you like) with the -l option. To set a fixed port manually use the -p option.

./udp-hello -l 0.0.0.0 -p 1337

The server will now wait for a datagram with the token 00. To change the token use the -T option:

./udp-hello -l 0.0.0.0 -p 1337 -T 1337C0DE
Start with Docker

There is an image available at https://hub.docker.com/r/x3rax/udp-hello. Use it like this:

listen='0.0.0.0'; port=1337; docker run --rm -p "${listen}:${port}:${port}/udp" -it x3rax/udp-hello -l 0.0.0.0 -p ${port} -T 1337C0DE
Send a Ping

You could for example use nmap to send a ping datagram with 1337C0DE as token:

# nmap example-host.tld -p 1337 -Pn -sU --data 1337C0DE

To use it for automated online detection use the "greppable output" and awk to parse it:

# nmap example.tld -p 1337 -Pn -sU --data 1337C0DE -oG - \
    | awk '
        BEGIN { open = 0; };
        { print $0 };
        !/^#/ {
            if ($4 == "Ports:") {
                split($5, s, "/");
                if (s[2] == "open") { open = 1; }
            }
        };
        END { if (!open) { exit 1 } }
    ' \
    && echo OK \
    || echo FAIL

(single line version)

# nmap example.tld -p 1337 -Pn -sU --data 1337C0DE -oG - | awk 'BEGIN { open = 0; }; { print $0 }; !/^#/ { if ($4 == "Ports:") { split($5, s, "/"); if (s[2] == "open") { open = 1; } } }; END { if (!open) { exit 1 } } ' && echo OK || echo FAIL

To mute output, remove the { print $0 } part.

Specific usecase is to reboot a Raspberry-PI if it looses connection to the internet over wifi:

#!/usr/bin/env bash

# IP and port of the udp-hello server
HOST='12.34.56.78'
PORT='1337'

TOKEN='1337C0DE'

# On which interface should the test be done?
INTERFACE='wlan0'

# How long to wait between online tests
INTERVAL=10

# When offline, how many seconds to wait before reboot
REBOOT_AFTER=60

ONLINE_TEST_TIMEOUT=10
ONLINE_TEST_MAX_RETRIES=3


function main() {
    lastOnline="$(date +%s)"

    for (( ; ; )); do
        now="$(date +%s)"
        if is-online; then
            lastOnline="$now"
        fi

        if (( (now - lastOnline) > REBOOT_AFTER )); then
            echo systemctl reboot
        fi

        sleep "$INTERVAL"
    done
}

function is-online() {
    nmap "$HOST" \
        -Pn \
        -e "$INTERFACE" \
        -p "$PORT" \
        -g 5050 \
        -sU \
        --data "$TOKEN" \
        --min-rtt-timeout "$ONLINE_TEST_TIMEOUT" \
        --max-rtt-timeout "$ONLINE_TEST_TIMEOUT" \
        --max-retries "$ONLINE_TEST_MAX_RETRIES" \
        -oG - \
    | awk '
        BEGIN { open = 0; };
        !/^#/ {
            if ($4 == "Ports:") {
                split($5, s, "/");
                if (s[2] == "open") { open = 1; }
            }
        };
        END { if (!open) { exit 1 } }
    '
    return $?
}


if (( $(id -u) != 0 )); then
    echo >&2 "Please run as root"
    exit 1
fi

main "$@"

Help Page

UDP Hello also has a help page available (this example might be outdated):

$ ./udp-hello -h

  Usage:
    udp-hello [OPTIONS]

  OPTIONS:
    -l, --listen    Address to listen on. Default is `127.0.0.1`.
    -p, --port      Port to listen on. Default is a random port.
    -q, --quiet     Do not log incoming requests. (Errors will still be logged.)
    -T, --token     Hex string containing a token. The server will only anser
                    if this token is received in the data section of a UDP
                    datagram. Default is `00`.
    -h, --help      Show this help message.

  EXAMPLE:
    # Listen publicly on port 1337, the token is ascii encoded 'hello'
    udp-hello --listen 0.0.0.0 -p 1337 -T 68656c6c6f0a

    # Do accept only if data section is empty (keep in mind that this will
    # reveal the port as open to a default `nmap` UDP scan)
    udp-hello --listen 0.0.0.0 -p 1337 -T ''

Tag summary

Content type

Image

Digest

Size

37.4 MB

Last updated

over 6 years ago

docker pull x3rax/udp-hello