From 24dbd9459d6854b97289410f3ef9ed21a231558e Mon Sep 17 00:00:00 2001 From: Juan Navarro Date: Mon, 19 Apr 2021 12:51:00 +0200 Subject: [PATCH 1/8] Use DNS requests to discover external IP address Using DNS requests is a much more robust and reliable method to discover a machine's external IP address, instead of the previous method of using Curl against an HTTP service. Using Curl is fine, but the kind of services that are typically used (here it was icanhazip.com, but there are lots more with a similar behavior) are are not as dependable as the official DNS request methods supported by some of the biggest service providers. This uses "dig", which Alpine provides in the package "bind-tools" and Debian in "dnstools". --- docker/coturn/alpine/Dockerfile | 3 + .../usr/local/bin/detect-external-ip.sh | 116 +++++++++++++++++- docker/coturn/debian/Dockerfile | 3 + .../usr/local/bin/detect-external-ip.sh | 116 +++++++++++++++++- 4 files changed, 230 insertions(+), 8 deletions(-) diff --git a/docker/coturn/alpine/Dockerfile b/docker/coturn/alpine/Dockerfile index ac06a36..05f0e4d 100644 --- a/docker/coturn/alpine/Dockerfile +++ b/docker/coturn/alpine/Dockerfile @@ -109,6 +109,9 @@ RUN apk update \ libpq mariadb-connector-c sqlite-libs \ hiredis \ mongo-c-driver \ + # Install `dig` tool for `detect-external-ip.sh`. + && apk add --no-cache \ + bind-tools \ # Cleanup unnecessary stuff. && rm -rf /var/cache/apk/* diff --git a/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh index b4e4c57..49bdc8d 100644 --- a/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh +++ b/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh @@ -1,7 +1,115 @@ -#!/bin/sh +#!/usr/bin/env sh +# shellcheck shell=dash -if [ -z "$REAL_EXTERNAL_IP" ]; then - export REAL_EXTERNAL_IP="$(curl -4 https://icanhazip.com 2>/dev/null)" +#/ 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 -exec echo "$REAL_EXTERNAL_IP" + + +# 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 + +echo "$COMMANDS" | while read -r COMMAND; do + if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then + echo "$IP" + exit 100 # Exits the pipe subshell. + fi +done + +if [ $? -eq 100 ]; then + exit 0 +else + echo "[$0] All providers failed" >&2 + exit 1 +fi diff --git a/docker/coturn/debian/Dockerfile b/docker/coturn/debian/Dockerfile index 7b64b39..0b4eeb0 100644 --- a/docker/coturn/debian/Dockerfile +++ b/docker/coturn/debian/Dockerfile @@ -164,6 +164,9 @@ RUN apt-get update \ libssl1.1 \ libpq5 libmariadb3 libsqlite3-0 \ libhiredis0.14 \ + # 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/* diff --git a/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh index b4e4c57..49bdc8d 100644 --- a/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh +++ b/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh @@ -1,7 +1,115 @@ -#!/bin/sh +#!/usr/bin/env sh +# shellcheck shell=dash -if [ -z "$REAL_EXTERNAL_IP" ]; then - export REAL_EXTERNAL_IP="$(curl -4 https://icanhazip.com 2>/dev/null)" +#/ 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 -exec echo "$REAL_EXTERNAL_IP" + + +# 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 + +echo "$COMMANDS" | while read -r COMMAND; do + if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then + echo "$IP" + exit 100 # Exits the pipe subshell. + fi +done + +if [ $? -eq 100 ]; then + exit 0 +else + echo "[$0] All providers failed" >&2 + exit 1 +fi From 8b8660530e0e2efb6faa9f8ad9e35db2a7abb144 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 20 Apr 2021 10:36:52 +0300 Subject: [PATCH 2/8] Avoid duplication via common rootfs/ dir --- .dockerignore | 1 + docker/coturn/alpine/Dockerfile | 1 + docker/coturn/debian/Dockerfile | 1 + .../usr/local/bin/detect-external-ip.sh | 115 ------------------ .../usr/local/bin/detect-external-ip.sh | 2 +- 5 files changed, 4 insertions(+), 116 deletions(-) delete mode 100644 docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh rename docker/coturn/{alpine => }/rootfs/usr/local/bin/detect-external-ip.sh (98%) diff --git a/.dockerignore b/.dockerignore index 8125ff6..7451c5a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,7 @@ !docker/coturn/alpine/ !docker/coturn/debian/ +!docker/coturn/rootfs/ !cmake/ !CMakeLists.txt diff --git a/docker/coturn/alpine/Dockerfile b/docker/coturn/alpine/Dockerfile index 05f0e4d..ef47d1f 100644 --- a/docker/coturn/alpine/Dockerfile +++ b/docker/coturn/alpine/Dockerfile @@ -78,6 +78,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 diff --git a/docker/coturn/debian/Dockerfile b/docker/coturn/debian/Dockerfile index 0b4eeb0..d295be1 100644 --- a/docker/coturn/debian/Dockerfile +++ b/docker/coturn/debian/Dockerfile @@ -129,6 +129,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 diff --git a/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh deleted file mode 100644 index 49bdc8d..0000000 --- a/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/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 - -echo "$COMMANDS" | while read -r COMMAND; do - if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then - echo "$IP" - exit 100 # Exits the pipe subshell. - fi -done - -if [ $? -eq 100 ]; then - exit 0 -else - echo "[$0] All providers failed" >&2 - exit 1 -fi diff --git a/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh similarity index 98% rename from docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh rename to docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh index 49bdc8d..50726c1 100644 --- a/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh +++ b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh @@ -103,7 +103,7 @@ fi echo "$COMMANDS" | while read -r COMMAND; do if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then echo "$IP" - exit 100 # Exits the pipe subshell. + exit 100 # Exits the pipe subshell. fi done From 4befd37d9ee2f5ba9ddca72380cfb3301fc2419b Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 20 Apr 2021 10:37:08 +0300 Subject: [PATCH 3/8] Fill up CHANGELOG --- docker/coturn/CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docker/coturn/CHANGELOG.md b/docker/coturn/CHANGELOG.md index 19e8e4c..c774d1a 100644 --- a/docker/coturn/CHANGELOG.md +++ b/docker/coturn/CHANGELOG.md @@ -4,6 +4,18 @@ Coturn TURN server Docker image changelog +## [4.5.2-r1] · 2021-04-?? · To-be-done +[4.5.2-r1]: /../../tree/docker/4.5.2-r1 + +### Changed + +- Use DNS requests to discover external IP address in `detect-external-ip` script ([#753]). + +[#753]: /../../pull/753 + + + + ## [4.5.2-r0] · 2021-04-15 [4.5.2-r0]: /../../tree/docker/4.5.2-r0 From e921203fdbec19f05dc0852b27fd2eef7ff94712 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 17 May 2021 19:02:33 +0300 Subject: [PATCH 4/8] Mention IPv6 detection capability in README of Docker image --- docker/coturn/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docker/coturn/README.md b/docker/coturn/README.md index 66c4a4b..32ae122 100644 --- a/docker/coturn/README.md +++ b/docker/coturn/README.md @@ -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 From e5af5a813fe4f5266f06c13745f49bfdb0770d37 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 17 May 2021 20:40:24 +0300 Subject: [PATCH 5/8] Get rid of nasty subshell in 'detect-external-ip' script of Docker image --- .../usr/local/bin/detect-external-ip.sh | 78 +++++++++---------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh index 50726c1..3dced9c 100644 --- a/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh +++ b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh @@ -36,7 +36,7 @@ # Shell options for strict error checking. for OPTION in errexit errtrace pipefail nounset; do - set -o | grep -wq "$OPTION" && set -o "$OPTION" + set -o | grep -wq "$OPTION" && set -o "$OPTION" done # Trace all commands (to stderr). @@ -48,8 +48,8 @@ done # ========================== if [ -n "${REAL_EXTERNAL_IP:-}" ]; then - echo "$REAL_EXTERNAL_IP" - exit 0 + echo "$REAL_EXTERNAL_IP" + exit 0 fi @@ -60,15 +60,15 @@ fi 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 + case "${1-}" in + --ipv4) CFG_IPV4="true" ;; + --ipv6) CFG_IPV4="false" ;; + *) + echo "Invalid argument: '${1-}'" >&2 + exit 1 + ;; + esac + shift done @@ -77,39 +77,35 @@ done # ================================ 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' + 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}$' - } + 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 \"' + 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 ] - } + 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 -echo "$COMMANDS" | while read -r COMMAND; do - if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then - echo "$IP" - exit 100 # Exits the pipe subshell. - fi +IFS=$'\n'; for COMMAND in $COMMANDS; do + if IP="$(eval "$COMMAND")" && is_valid_ip "$IP"; then + printf '%s' "$IP" + exit 0 + fi done -if [ $? -eq 100 ]; then - exit 0 -else - echo "[$0] All providers failed" >&2 - exit 1 -fi +echo "[$0] All providers failed" >&2 +exit 1 From 7ed7c438a7db43cad50fc071d7a9030b8a091990 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 17 May 2021 20:40:49 +0300 Subject: [PATCH 6/8] Add tests for 'detect-external-ip' script of Docker image --- docker/coturn/tests/main.bats | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docker/coturn/tests/main.bats b/docker/coturn/tests/main.bats index 73e238f..93a2aeb 100644 --- a/docker/coturn/tests/main.bats +++ b/docker/coturn/tests/main.bats @@ -125,3 +125,76 @@ [ "$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" { + 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 +} From 484c88ea2af9a2dde982f81704f1cf057141faa3 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 17 May 2021 21:09:00 +0300 Subject: [PATCH 7/8] Disable IPv6 tests of Docker image by default --- docker/coturn/Makefile | 2 ++ docker/coturn/tests/main.bats | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docker/coturn/Makefile b/docker/coturn/Makefile index 99b46f2..3910411 100644 --- a/docker/coturn/Makefile +++ b/docker/coturn/Makefile @@ -176,6 +176,7 @@ docker.push: # [( [build=no] # | build=yes [DOCKERFILE=(debian|alpine)] # [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 diff --git a/docker/coturn/tests/main.bats b/docker/coturn/tests/main.bats index 93a2aeb..e093a1a 100644 --- a/docker/coturn/tests/main.bats +++ b/docker/coturn/tests/main.bats @@ -149,6 +149,8 @@ } @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 ] From f2f8796e8ca23361bca95663c7a182c62df2be05 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 17 May 2021 23:38:38 +0300 Subject: [PATCH 8/8] Hack IFS in 'detect-external-ip' script of Docker image to support both Debian and Alpine --- docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh index 3dced9c..c019c2f 100644 --- a/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh +++ b/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh @@ -100,7 +100,8 @@ else } fi -IFS=$'\n'; for COMMAND in $COMMANDS; do +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