Merge pull request #49 from termux/dnsmasq

Switch to dynamic DNS host name resolution. Implemented using dnsmasq as suggested in https://github.com/termux/termux-docker/issues/48.

The dnsmasq server is started by entrypoint script before launching the actual command or shell. This will have side effect on usage: container must always be started as root.
This commit is contained in:
Leonid Pliushch
2023-02-22 22:32:48 +02:00
committed by GitHub
18 changed files with 75 additions and 159 deletions

View File

@@ -13,9 +13,8 @@ ENV PATH /system/bin
# Copy libc, linker and few utilities. # Copy libc, linker and few utilities.
COPY /system/$SYSTEM_TYPE /system COPY /system/$SYSTEM_TYPE /system
# Static DNS hosts: as our system does not have a DNS resolver, we will # Copy entrypoint script.
# have to resolve domains manually and fill /system/etc/hosts. COPY /entrypoint.sh /entrypoint.sh
COPY /static-dns-hosts.txt /system/etc/static-dns-hosts.txt
# Extract bootstrap archive and create symlinks. # Extract bootstrap archive and create symlinks.
ADD https://github.com/termux/termux-packages/releases/download/bootstrap-$BOOTSTRAP_VERSION/bootstrap-$BOOTSTRAP_ARCH.zip /bootstrap.zip ADD https://github.com/termux/termux-packages/releases/download/bootstrap-$BOOTSTRAP_VERSION/bootstrap-$BOOTSTRAP_ARCH.zip /bootstrap.zip
@@ -38,7 +37,7 @@ RUN busybox mkdir -p /data/data/com.termux/files && \
# Link some utilities to busybox. # Link some utilities to busybox.
# Some utilities in $PREFIX are actually a wrapper of the same binary # Some utilities in $PREFIX are actually a wrapper of the same binary
# from /system/bin. See termux-tools/build.sh#L29. # from /system/bin. See termux-tools/build.sh#L29.
RUN for tool in df mount ping ping6 top umount; do \ RUN for tool in df mount ping ping6 su top umount; do \
busybox ln -s /system/bin/busybox /system/bin/$tool; \ busybox ln -s /system/bin/busybox /system/bin/$tool; \
done done
@@ -48,7 +47,8 @@ RUN for tool in df mount ping ping6 top umount; do \
# * Rest is owned by root and has 755/644 modes. # * Rest is owned by root and has 755/644 modes.
RUN busybox chown -Rh 0:0 /system && \ RUN busybox chown -Rh 0:0 /system && \
busybox chown -Rh 1000:1000 /data/data/com.termux && \ busybox chown -Rh 1000:1000 /data/data/com.termux && \
busybox chown 1000:1000 /system/etc/hosts /system/etc/static-dns-hosts.txt && \ busybox ln -s /system/etc/passwd /etc/passwd && \
busybox ln -s /system/etc/group /etc/group && \
busybox find /system -type d -exec busybox chmod 755 "{}" \; && \ busybox find /system -type d -exec busybox chmod 755 "{}" \; && \
busybox find /system -type f -executable -exec busybox chmod 755 "{}" \; && \ busybox find /system -type f -executable -exec busybox chmod 755 "{}" \; && \
busybox find /system -type f ! -executable -exec busybox chmod 644 "{}" \; && \ busybox find /system -type f ! -executable -exec busybox chmod 644 "{}" \; && \
@@ -57,26 +57,12 @@ RUN busybox chown -Rh 0:0 /system && \
cd /data/data/com.termux/files/usr && \ cd /data/data/com.termux/files/usr && \
busybox find ./bin ./lib/apt ./libexec -type f -exec busybox chmod 700 "{}" \; busybox find ./bin ./lib/apt ./libexec -type f -exec busybox chmod 700 "{}" \;
# Switch user to non-root.
USER 1000:1000
# Update static DNS cache on login. Also symlink script and host list to prefix.
RUN echo "echo -e 'Updating static DNS:\n' && /system/bin/update-static-dns && echo" \
> /data/data/com.termux/files/home/.bashrc && \
busybox ln -s /system/bin/update-static-dns /data/data/com.termux/files/usr/bin/update-static-dns && \
busybox ln -s /system/etc/static-dns-hosts.txt /data/data/com.termux/files/usr/etc/static-dns-hosts.txt
# Create empty user static DNS cache (external bind)
RUN busybox mkdir -p /data/data/com.termux/files/home/.termux/termux-docker/ && \
busybox touch /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt && \
busybox chown 1000:1000 /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt
# Update static DNS cache, install updates and cleanup when not building for arm. # Update static DNS cache, install updates and cleanup when not building for arm.
ENV PATH /data/data/com.termux/files/usr/bin ENV PATH /data/data/com.termux/files/usr/bin
RUN if [ ${BOOTSTRAP_ARCH} == 'arm' ]; then exit; else \ RUN if [ ${BOOTSTRAP_ARCH} == 'arm' ]; then exit; else \
update-static-dns && \ /system/bin/sh -T /dev/ptmx -c "/system/bin/dnsmasq -u root -g root --pid-file /dnsmasq.pid" && sleep 1 && \
apt update && \ su - system -c "/data/data/com.termux/files/usr/bin/apt update" && \
apt upgrade -o Dpkg::Options::=--force-confnew -yq && \ su - system -c "/data/data/com.termux/files/usr/bin/apt upgrade -o Dpkg::Options::=--force-confnew -yq" && \
rm -rf /data/data/com.termux/files/usr/var/lib/apt/* && \ rm -rf /data/data/com.termux/files/usr/var/lib/apt/* && \
rm -rf /data/data/com.termux/files/usr/var/log/apt/* && \ rm -rf /data/data/com.termux/files/usr/var/log/apt/* && \
rm -rf /data/data/com.termux/cache/apt/* ;\ rm -rf /data/data/com.termux/cache/apt/* ;\
@@ -99,6 +85,6 @@ COPY --from=bootstrap / /
WORKDIR /data/data/com.termux/files/home WORKDIR /data/data/com.termux/files/home
SHELL ["/data/data/com.termux/files/usr/bin/sh", "-c"] SHELL ["/data/data/com.termux/files/usr/bin/sh", "-c"]
USER 1000:1000
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/data/data/com.termux/files/usr/bin/login"] CMD ["/data/data/com.termux/files/usr/bin/login"]

View File

@@ -42,12 +42,6 @@ There a number of known issues which may not be resolved:
* ARM containers may require a custom seccomp profile to remove restrictions from * ARM containers may require a custom seccomp profile to remove restrictions from
`personality()` system call. `personality()` system call.
* DNS: Docker image has to use a static DNS resolver through `/system/etc/hosts`.
You can regenerate this file by editing `/system/etc/static-dns-hosts.txt` or
`/data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt` (aka
`~/.termux/termux-docker/static-dns-hosts.txt`) (this is preferable for docker binds)
and executing script `/system/bin/update-static-dns`.
* When running certain multi threaded program in 32bit containers, the PIDs can * When running certain multi threaded program in 32bit containers, the PIDs can
balloon and easily exceed libc's limit. The only way to fix this is to set balloon and easily exceed libc's limit. The only way to fix this is to set
`/proc/sys/kernel/pid_max` to 65536. See [termux-docker#40](https://github.com/termux/termux-docker/issues/40). `/proc/sys/kernel/pid_max` to 65536. See [termux-docker#40](https://github.com/termux/termux-docker/issues/40).

21
entrypoint.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/system/bin/sh
if [ "$(id -u)" = "0" ] && [ -z "$(/system/bin/busybox pidof dnsmasq)" ]; then
/system/bin/sh -T /dev/ptmx -c "/system/bin/dnsmasq -u root -g root --pid-file /dnsmasq.pid" >/dev/null 2>&1
sleep 1
if [ -z "$(/system/bin/busybox pidof dnsmasq)" ]; then
echo "[!] Failed to start dnsmasq, host name resolution may fail." >&2
fi
else
echo "[!] Container is running as non-root, unable to start dnsmasq. DNS will be unavailable." >&2
fi
if [ $# -ge 1 ]; then
exec "$@"
else
if [ "$(id -u)" = "0" ]; then
exec /system/bin/su - system -c "/data/data/com.termux/files/usr/bin/login"
else
exec /data/data/com.termux/files/usr/bin/login
fi
fi

View File

@@ -1,60 +0,0 @@
##
## Termux Docker environment doesn't have working DNS resolver.
## This list contains domains that will be manually resolved. Result
## will be used to fill /system/etc/hosts.
##
# Termux repositories:
termux.net
termux.org
packages.termux.org
packages-cf.termux.org
packages.termux.dev
packages-cf.termux.dev
# Termux mirrors:
deb.kcubeterm.me
dl.kcubeterm.com
grimler.se
termux.mentality.rip
mirrors.bfsu.edu.cn
mirrors.tuna.tsinghua.edu.cn
mirrors.ustc.edu.cn
packages.kcubeterm.me
packages.kcubeterm.com
termux.astra.in.ua
mirror.bardia.tech
# Community repositories:
its-pointless.github.io
termux-pod.github.io
# Github:
github.com
objects.githubusercontent.com
codeload.github.com
gist.github.com
gist.githubusercontent.com
github-releases.githubusercontent.com
raw.githubusercontent.com
# Perl:
www.cpan.org
# Python package manager (pip):
pypi.org
test.pypi.org
upload.pypi.org
pythonhosted.org
files.pythonhosted.org
test-files.pythonhosted.org
# Ruby package manager (gem):
rubygems.org
index.rubygems.org
# Node package manager (npm):
registry.npmjs.org
# Yarn package manager (yarn):
registry.yarnpkg.com

BIN
system/arm/bin/dnsmasq Executable file

Binary file not shown.

View File

@@ -1 +0,0 @@
busybox

BIN
system/arm/bin/sh Executable file

Binary file not shown.

View File

@@ -1,35 +0,0 @@
#!/system/bin/sh
export PATH=/system/bin
echo "127.0.0.1 localhost $(busybox hostname)" > /system/etc/hosts
echo "::1 ip6-localhost" >> /system/etc/hosts
# IPv4
for host in $(busybox cat /system/etc/static-dns-hosts.txt /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt | busybox grep -vE '^\s*#'); do
ip_addr=$(busybox nslookup -type=a "$host" 8.8.8.8 | busybox awk '/^Address: / { print $2 ; exit }')
if [ -z "$ip_addr" ]; then
echo "Can't resolve '$host'." >&2
continue
fi
echo "$ip_addr $host" | busybox tee -a /system/etc/hosts
done
# Check whether IPv6 is available.
busybox wget http://[2606:4700:4700::1111] -O /dev/null -o /dev/null
if [[ $? != 0 ]]; then
exit
fi
# IPv6
for host in $(busybox cat /system/etc/static-dns-hosts.txt /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt | busybox grep -vE '^\s*#'); do
ip_addr=$(busybox nslookup -type=aaaa "$host" 2001:4860:4860::8888 | busybox awk '/^Address: / { print $2 ; exit }')
if [ -z "$ip_addr" ]; then
echo "Can't resolve '$host'." >&2
continue
fi
echo "$ip_addr $host" | busybox tee -a /system/etc/hosts
done

2
system/arm/etc/group Normal file
View File

@@ -0,0 +1,2 @@
root:x:0:
system:!:1000:system

21
system/arm/etc/mkshrc Normal file
View File

@@ -0,0 +1,21 @@
# Copyright (c) 2010, 2012, 2013, 2014
# Thorsten Glaser <tg@mirbsd.org>
# This file is provided under the same terms as mksh.
#-
# Minimal /system/etc/mkshrc for Android
#
# Support: https://launchpad.net/mksh
: ${HOSTNAME:=$(getprop ro.product.device)}
: ${HOSTNAME:=android}
: ${TMPDIR:=/data/local/tmp}
export HOSTNAME TMPDIR
if (( USER_ID )); then PS1='$'; else PS1='#'; fi
PS4='[$EPOCHREALTIME] '; PS1='${|
local e=$?
(( e )) && REPLY+="$e|"
return $e
}$HOSTNAME:${PWD:-?} '"$PS1 "

2
system/arm/etc/passwd Normal file
View File

@@ -0,0 +1,2 @@
root:x:0:0:root:/:/system/bin/sh
system:x:1000:1000:system:/data/data/com.termux/files/home:/data/data/com.termux/files/usr/bin/login

BIN
system/arm/lib/libcutils.so Normal file

Binary file not shown.

BIN
system/x86/bin/dnsmasq Executable file

Binary file not shown.

View File

@@ -1 +0,0 @@
busybox

BIN
system/x86/bin/sh Executable file

Binary file not shown.

View File

@@ -1,35 +0,0 @@
#!/system/bin/sh
export PATH=/system/bin
echo "127.0.0.1 localhost $(busybox hostname)" > /system/etc/hosts
echo "::1 ip6-localhost" >> /system/etc/hosts
# IPv4
for host in $(busybox cat /system/etc/static-dns-hosts.txt /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt | busybox grep -vE '^\s*#'); do
ip_addr=$(busybox nslookup -type=a "$host" 8.8.8.8 | busybox awk '/^Address: / { print $2 ; exit }')
if [ -z "$ip_addr" ]; then
echo "Can't resolve '$host'." >&2
continue
fi
echo "$ip_addr $host" | busybox tee -a /system/etc/hosts
done
# Check whether IPv6 is available.
busybox wget http://[2606:4700:4700::1111] -O /dev/null -o /dev/null
if [[ $? != 0 ]]; then
exit
fi
# IPv6
for host in $(busybox cat /system/etc/static-dns-hosts.txt /data/data/com.termux/files/home/.termux/termux-docker/static-dns-hosts.txt | busybox grep -vE '^\s*#'); do
ip_addr=$(busybox nslookup -type=aaaa "$host" 2001:4860:4860::8888 | busybox awk '/^Address: / { print $2 ; exit }')
if [ -z "$ip_addr" ]; then
echo "Can't resolve '$host'." >&2
continue
fi
echo "$ip_addr $host" | busybox tee -a /system/etc/hosts
done

2
system/x86/etc/group Normal file
View File

@@ -0,0 +1,2 @@
root:x:0:
system:!:1000:system

16
system/x86/etc/mkshrc Normal file
View File

@@ -0,0 +1,16 @@
# Copyright (c) 2010, 2012, 2013, 2014
# Thorsten Glaser <tg@mirbsd.org>
# This file is provided under the same terms as mksh.
#-
# Minimal /system/etc/mkshrc for Android
#
# Support: https://launchpad.net/mksh
if (( USER_ID )); then PS1='$'; else PS1='#'; fi
PS4='[$EPOCHREALTIME] '; PS1='${|
local e=$?
(( e )) && REPLY+="$e|"
return $e
}$HOSTNAME:${PWD:-?} '"$PS1 "

2
system/x86/etc/passwd Normal file
View File

@@ -0,0 +1,2 @@
root:x:0:0:root:/:/system/bin/sh
system:x:1000:1000:system:/data/data/com.termux/files/home:/data/data/com.termux/files/usr/bin/login

BIN
system/x86/lib/libcutils.so Normal file

Binary file not shown.