Merge pull request #753 from j1elo/master
Use DNS requests to discover external IP address
This commit is contained in:
commit
55b506c4a2
@ -2,6 +2,7 @@
|
||||
|
||||
!docker/coturn/alpine/
|
||||
!docker/coturn/debian/
|
||||
!docker/coturn/rootfs/
|
||||
|
||||
!cmake/
|
||||
!CMakeLists.txt
|
||||
|
||||
@ -11,10 +11,15 @@ Coturn TURN server Docker image changelog
|
||||
|
||||
- [Prometheus] support with [prometheus-client-c] 0.1.3: <https://github.com/digitalocean/prometheus-client-c/releases/tag/v0.1.3> ([#754])
|
||||
|
||||
### Improved
|
||||
|
||||
- Use DNS requests to discover external IP address in `detect-external-ip` script ([#753]).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect linking with [mongo-c-driver] on [Debian Linux] image.
|
||||
|
||||
[#753]: /../../pull/753
|
||||
[#754]: /../../pull/754
|
||||
|
||||
|
||||
|
||||
@ -176,6 +176,7 @@ docker.push:
|
||||
# [( [build=no]
|
||||
# | build=yes [DOCKERFILE=(debian|alpine)]
|
||||
# [ref=<git-ref>] )]
|
||||
# [with=ipv6]
|
||||
|
||||
test-docker-platforms = $(strip $(if $(call eq,$(platforms),),$(MAIN_PLATFORM),\
|
||||
$(if $(call eq,$(platforms),@all),$(PLATFORMS),\
|
||||
@ -195,6 +196,7 @@ define test.docker.do
|
||||
@make docker.image DOCKERFILE=$(DOCKERFILE) \
|
||||
no-cache=no tag=$(tag) platform=$(platform) ref=$(ref) ,)
|
||||
IMAGE=coturn/$(NAME):$(tag) PLATFORM=$(platform) \
|
||||
$(if $(call eq,$(with),ipv6),TEST_IPV6=1,) \
|
||||
node_modules/.bin/bats \
|
||||
--timing $(if $(call eq,$(CI),),--pretty,--formatter tap) \
|
||||
tests/main.bats
|
||||
|
||||
@ -110,6 +110,14 @@ docker run -d --network=host coturn/coturn \
|
||||
--relay-ip='$(detect-external-ip)'
|
||||
```
|
||||
|
||||
By default, [IPv4] address is discovered. In case you need an [IPv6] one, specify the `--ipv6` flag:
|
||||
```bash
|
||||
docker run -d --network=host coturn/coturn \
|
||||
-n --log-file=stdout \
|
||||
--external-ip='$(detect-external-ip --ipv6)' \
|
||||
--relay-ip='$(detect-external-ip --ipv6)'
|
||||
```
|
||||
|
||||
|
||||
### Persistence
|
||||
|
||||
@ -185,6 +193,8 @@ If you have any problems with or questions about this image, please contact us t
|
||||
|
||||
|
||||
[DockerHub]: https://hub.docker.com
|
||||
[IPv4]: https://en.wikipedia.org/wiki/IPv4
|
||||
[IPv6]: https://en.wikipedia.org/wiki/IPv6
|
||||
[RFC 5766 Section 6.2]: https://tools.ietf.org/html/rfc5766.html#section-6.2
|
||||
|
||||
[1]: http://alpinelinux.org
|
||||
|
||||
@ -150,6 +150,7 @@ RUN mkdir -p /out/ \
|
||||
&& rm -f /out/etc/coturn/turnserver.conf.default
|
||||
|
||||
# Install helper tools of Docker image.
|
||||
COPY docker/coturn/rootfs/ /out/
|
||||
COPY docker/coturn/alpine/rootfs/ /out/
|
||||
RUN chmod +x /out/usr/local/bin/docker-entrypoint.sh \
|
||||
/out/usr/local/bin/detect-external-ip.sh
|
||||
@ -185,6 +186,9 @@ RUN apk update \
|
||||
hiredis \
|
||||
mongo-c-driver \
|
||||
libmicrohttpd \
|
||||
# Install `dig` tool for `detect-external-ip.sh`.
|
||||
&& apk add --no-cache \
|
||||
bind-tools \
|
||||
# Cleanup unnecessary stuff.
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$REAL_EXTERNAL_IP" ]; then
|
||||
export REAL_EXTERNAL_IP="$(curl -4 https://icanhazip.com 2>/dev/null)"
|
||||
fi
|
||||
|
||||
exec echo "$REAL_EXTERNAL_IP"
|
||||
@ -207,6 +207,7 @@ RUN mkdir -p /out/ \
|
||||
&& rm -f /out/etc/coturn/turnserver.conf.default
|
||||
|
||||
# Install helper tools of Docker image.
|
||||
COPY docker/coturn/rootfs/ /out/
|
||||
COPY docker/coturn/debian/rootfs/ /out/
|
||||
RUN chmod +x /out/usr/local/bin/docker-entrypoint.sh \
|
||||
/out/usr/local/bin/detect-external-ip.sh
|
||||
@ -246,6 +247,9 @@ RUN apt-get update \
|
||||
libpq5 libmariadb3 libsqlite3-0 \
|
||||
libhiredis0.14 \
|
||||
libmicrohttpd12 \
|
||||
# Install `dig` tool for `detect-external-ip.sh`.
|
||||
&& apt-get install -y --no-install-recommends --no-install-suggests \
|
||||
dnsutils \
|
||||
# Cleanup unnecessary stuff.
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$REAL_EXTERNAL_IP" ]; then
|
||||
export REAL_EXTERNAL_IP="$(curl -4 https://icanhazip.com 2>/dev/null)"
|
||||
fi
|
||||
|
||||
exec echo "$REAL_EXTERNAL_IP"
|
||||
112
docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh
Normal file
112
docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh
Normal file
@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck shell=dash
|
||||
|
||||
#/ Use DNS to find out about the external IP of the running system.
|
||||
#/
|
||||
#/ This script is useful when running from a machine that sits behind a NAT.
|
||||
#/ Due to how NAT works, machines behind it belong to an internal or private
|
||||
#/ subnet, with a different address space than the external or public side.
|
||||
#/
|
||||
#/ Typically it is possible to make an HTTP request to a number of providers
|
||||
#/ that offer the external IP in their response body (eg: ifconfig.me). However,
|
||||
#/ why do a slow and heavy HTTP request, when DNS exists and is much faster?
|
||||
#/ Well established providers such as OpenDNS or Google offer special hostnames
|
||||
#/ that, when resolved, will actually return the IP address of the caller.
|
||||
#/
|
||||
#/ https://unix.stackexchange.com/questions/22615/how-can-i-get-my-external-ip-address-in-a-shell-script/81699#81699
|
||||
#/
|
||||
#/
|
||||
#/ Arguments
|
||||
#/ ---------
|
||||
#/
|
||||
#/ --ipv4
|
||||
#/
|
||||
#/ Find the external IPv4 address.
|
||||
#/ Optional. Default: Enabled.
|
||||
#/
|
||||
#/ --ipv6
|
||||
#/
|
||||
#/ Find the external IPv6 address.
|
||||
#/ Optional. Default: Disabled.
|
||||
|
||||
|
||||
|
||||
# Shell setup
|
||||
# ===========
|
||||
|
||||
# Shell options for strict error checking.
|
||||
for OPTION in errexit errtrace pipefail nounset; do
|
||||
set -o | grep -wq "$OPTION" && set -o "$OPTION"
|
||||
done
|
||||
|
||||
# Trace all commands (to stderr).
|
||||
#set -o xtrace
|
||||
|
||||
|
||||
|
||||
# Shortcut: REAL_EXTERNAL_IP
|
||||
# ==========================
|
||||
|
||||
if [ -n "${REAL_EXTERNAL_IP:-}" ]; then
|
||||
echo "$REAL_EXTERNAL_IP"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Parse call arguments
|
||||
# ====================
|
||||
|
||||
CFG_IPV4="true"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "${1-}" in
|
||||
--ipv4) CFG_IPV4="true" ;;
|
||||
--ipv6) CFG_IPV4="false" ;;
|
||||
*)
|
||||
echo "Invalid argument: '${1-}'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
|
||||
# Discover the external IP address
|
||||
# ================================
|
||||
|
||||
if [ "$CFG_IPV4" = "true" ]; then
|
||||
COMMANDS='dig @resolver1.opendns.com myip.opendns.com A -4 +short
|
||||
dig @ns1.google.com o-o.myaddr.l.google.com TXT -4 +short | tr -d \"
|
||||
dig @1.1.1.1 whoami.cloudflare TXT CH -4 +short | tr -d \"
|
||||
dig @ns1-1.akamaitech.net whoami.akamai.net A -4 +short'
|
||||
|
||||
is_valid_ip() {
|
||||
# Check if the input looks like an IPv4 address.
|
||||
# Doesn't check if the actual values are valid; assumes they are.
|
||||
echo "$1" | grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
|
||||
}
|
||||
else
|
||||
COMMANDS='dig @resolver1.opendns.com myip.opendns.com AAAA -6 +short
|
||||
dig @ns1.google.com o-o.myaddr.l.google.com TXT -6 +short | tr -d \"
|
||||
dig @2606:4700:4700::1111 whoami.cloudflare TXT CH -6 +short | tr -d \"'
|
||||
|
||||
is_valid_ip() {
|
||||
# Check if the input looks like an IPv6 address.
|
||||
# It's almost impossible to check the IPv6 representation because it
|
||||
# varies wildly, so just check that there are at least 2 colons.
|
||||
[ "$(echo "$1" | awk -F':' '{print NF-1}')" -ge 2 ]
|
||||
}
|
||||
fi
|
||||
|
||||
IFS="$(printf '\nx')" && IFS="${IFS%x}"
|
||||
for COMMAND in $COMMANDS; do
|
||||
if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then
|
||||
printf '%s' "$IP"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[$0] All providers failed" >&2
|
||||
exit 1
|
||||
@ -125,3 +125,78 @@
|
||||
[ "$status" -eq 0 ]
|
||||
[ ! "$output" = '' ]
|
||||
}
|
||||
|
||||
|
||||
@test "detect-external-ip is present" {
|
||||
run docker run --rm --platform $PLATFORM --entrypoint sh $IMAGE -c \
|
||||
'which detect-external-ip'
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "detect-external-ip runs ok" {
|
||||
run docker run --rm --platform $PLATFORM --entrypoint sh $IMAGE -c \
|
||||
'detect-external-ip'
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "detect-external-ip returns valid IPv4" {
|
||||
run docker run --rm --platform $PLATFORM --entrypoint sh $IMAGE -c \
|
||||
'detect-external-ip --ipv4'
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run validate_ipv4 "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "detect-external-ip returns valid IPv6" {
|
||||
[ -z "$TEST_IPV6" ] && skip
|
||||
|
||||
run docker run --rm --platform $PLATFORM --entrypoint sh $IMAGE -c \
|
||||
'detect-external-ip --ipv6'
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run validate_ipv6 "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "detect-external-ip returns IPv4 by default" {
|
||||
run docker run --rm --platform $PLATFORM --entrypoint sh $IMAGE -c \
|
||||
'detect-external-ip --ipv4'
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run validate_ipv4 "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Helpers
|
||||
#
|
||||
|
||||
# Tests the IP address to be a valid IPv4 address.
|
||||
function validate_ipv4() {
|
||||
local ip=$1
|
||||
local stat=1
|
||||
|
||||
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
OIFS=$IFS
|
||||
IFS='.'
|
||||
ip=($ip)
|
||||
IFS=$OIFS
|
||||
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
|
||||
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
|
||||
stat=$?
|
||||
fi
|
||||
return $stat
|
||||
}
|
||||
|
||||
# Tests the IP address to be a valid IPv6 address.
|
||||
function validate_ipv6() {
|
||||
local ip=$1
|
||||
local stat=1
|
||||
|
||||
if [[ $ip =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]]; then
|
||||
stat=0
|
||||
fi
|
||||
return $stat
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user