"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.
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
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
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 "$@"
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 ''
Content type
Image
Digest
Size
37.4 MB
Last updated
over 6 years ago
docker pull x3rax/udp-hello