Improve the method to set route for open ports

Fix #20
This commit is contained in:
Hagb Green
2021-07-04 04:07:58 +08:00
parent a54c3e1a57
commit 345eac297f
7 changed files with 70 additions and 23 deletions

View File

@@ -5,8 +5,7 @@ RUN sed -i s/deb.debian.org/mirrors.cqu.edu.cn/ /etc/apt/sources.list &&\
apt-get install -y --no-install-recommends --no-install-suggests \
libgtk2.0-0 libx11-xcb1 libxtst6 libnss3 libasound2 libdbus-glib-1-2 iptables xclip\
dante-server tigervnc-standalone-server tigervnc-common dante-server psmisc flwm x11-utils\
busybox libssl-dev && \
ln -s "$(which busybox)" /usr/local/bin/ip
busybox libssl-dev iproute2
ARG EC_URL

View File

@@ -3,8 +3,8 @@ FROM debian:buster-slim
RUN sed -i s/deb.debian.org/mirrors.cqu.edu.cn/ /etc/apt/sources.list &&\
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests iptables \
dante-server busybox && \
for command in ip ps kill killall; do ln -s "$(which busybox)" /usr/local/bin/"${command}" || exit 1 ; done
dante-server busybox iproute2 && \
for command in ps kill killall; do ln -s "$(which busybox)" /usr/local/bin/"${command}" || exit 1 ; done
ARG EC_CLI_URL="https://github.com/shmilee/scripts/releases/download/v0.0.1/easyconn_7.6.8.2-ubuntu_amd64.deb"

View File

@@ -4,8 +4,7 @@ RUN sed -i s/deb.debian.org/mirrors.cqu.edu.cn/ /etc/apt/sources.list &&\
apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests \
libgtk2.0-0 libx11-xcb1 libxtst6 libnss3 libasound2 libdbus-glib-1-2 iptables \
dante-server psmisc libxaw7 xclip busybox libssl-dev &&\
ln -s "$(which busybox)" /usr/local/bin/ip
dante-server psmisc libxaw7 xclip busybox libssl-dev iproute2
RUN cd tmp && apt update && apt download x11-utils && dpkg -x x11-utils_*.deb x11-utils &&\
mkdir -p /usr/local/bin && cp x11-utils/usr/bin/xmessage /usr/local/bin && rm -r x11-utils*

View File

@@ -209,6 +209,10 @@ docker run --device /dev/net/tun --cap-add NET_ADMIN -ti -e PASSWORD=xxxx -v $HO
## 已知问题
### 除宿主机外其他设备无法访问容器的开放端口
见 [路由和开放端口说明](doc/route.md)。
### 出现多条报错:`Couldn't load match 'state':No such file or directory` 或 `ip: RTNETLINK answers: Operation not permitted`
此为运行环境不支持 nft 且未被容器脚本检测出来所致。可以通过设置环境变量 `IPTABLES_LEGACY` 为 `1` 明确让容器使用 legacy iptables 来解决。

24
doc/route.md Normal file
View File

@@ -0,0 +1,24 @@
# 路由和开放端口说明
## TL;DR
用 docker 向外开放了端口时EasyConnect 设置的路由表可能会使开放端口无法被宿主机外的设备直接访问。为了使这些开放端口可被其他设备访问,需要设置恰当的路由策略。(如无此需求可忽略)
宿主机应满足以下条件的至少一条:
- Linux 内核版本不小于 `4.17-rc1`。内核版本可通过 `uname -r` 获取。
- 使用 [`nftables`](https://netfilter.org/projects/nftables/)。可通过 `sudo iptables -V | grep nf_tables` 输出是否为空来判断(非空则表明在使用 `nftables`)。
- `iptable_mangle``xt_mark` 模块被编译进内核或作为模块加载加载。
可通过以下命令来快速检查(其中 `TAG` 替换成实际使用的 tag
``` bash
docker run --cap-add NET_ADMIN -e DETECT_ROUTE_ONLY=1 hagb/docker-easyconnect:TAG
```
若输出 `Can't find available method to automatically set route for opening ports (refer to https://github.com/Hagb/docker-easyconnect/tree/master/doc/ports.md)` 字样的报错,则说明不满足以上条件。
群辉系统可通过加载 `iptable_mangle` 和 `xt_mark` 模块来解决:
```bash
sudo insmod /lib/modules/iptable_mangle.ko
sudo insmod /lib/modules/xt_mark.ko
```

View File

@@ -0,0 +1,28 @@
#!/bin/bash
# 设置策略路由使宿主机外的机器能够访问容器提供的服务
## 将路由表 main 备份到路由表 2
(
ip route flush table 2
IFS="
"
for i in $(ip route show); do IFS=' '; ip route add $i table 2 ; done
)
## 确定策略路由方式
ip rule add iif lo table 2 sport 1080
if ip rule show iif lo table 2 | grep sport >/dev/null ; then
ip rule add fwmark 1 table 2
open_port() { ip rule add iif lo table 2 sport $1; }
close_port() { ip rule del iif lo table 2 sport $1; }
elif iptables -t mangle -A OUTPUT -j MARK --set-mark 1 -p tcp --sport 1080 2>/dev/null ; then
iptables -t mangle -D OUTPUT -j MARK --set-mark 1 -p tcp --sport 1080
open_port() { iptables -t mangle -I OUTPUT -j MARK --set-mark 1 -p tcp --sport $1; }
close_port() { iptables -t mangle -D OUTPUT -j MARK --set-mark 1 -p tcp --sport $1; }
else
open_port() { true; }
close_port() { true; }
echo "Can't find available method to automatically set route for opening ports"\
"(refer to https://github.com/Hagb/docker-easyconnect/tree/master/doc/route.md)" >&2
fi
ip rule del iif lo sport 1080 table 2

View File

@@ -11,30 +11,22 @@ else
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
fi
. "$(which detect-route.sh)"
[ -n "DETECT_ROUTE_ONLY" ] && exit
# 在虚拟网络设备 tun0 打开时运行 proxy 代理服务器
[ -n "$NODANTED" ] || (while true
do
sleep 5
[ -d /sys/class/net/tun0 ] && { chmod a+w /tmp ; su daemon -s /usr/sbin/danted; }
[ -d /sys/class/net/tun0 ] && {
chmod a+w /tmp
open_port 1080
su daemon -s /usr/sbin/danted
close_port 1080
}
done
)&
# https://github.com/Hagb/docker-easyconnect/issues/20
# https://serverfault.com/questions/302936/configuring-route-to-use-the-same-interface-for-outbound-traffic-as-that-of-inbo
iptables -t mangle -I OUTPUT -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
iptables -t mangle -I INPUT -m connmark ! --mark 0 -j CONNMARK --save-mark
iptables -t mangle -I INPUT -m connmark --mark 1 -j MARK --set-mark 1
iptables -t mangle -I INPUT -i eth0 -j CONNMARK --set-mark 1
(
IFS="
"
for i in $(ip route show); do
IFS=' '
ip route add $i table 2
done
ip rule add fwmark 1 table 2
)
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
# 拒绝 tun0 侧主动请求的连接.
@@ -74,6 +66,7 @@ then
[ -e ~/.vnc/passwd ] || (mkdir -p ~/.vnc && (echo password | tigervncpasswd -f > ~/.vnc/passwd))
[ -n "$PASSWORD" ] && printf %s "$PASSWORD" | tigervncpasswd -f > ~/.vnc/passwd
open_port 5901
tigervncserver :1 -geometry 800x600 -localhost no -passwd ~/.vnc/passwd -xstartup flwm
DISPLAY=:1