构建 Privoxy、Tor、ExpressVPN 的 Docker 镜像

前言

教程目标

构建集成了 Privoxy、Tor、ExpressVPN、SpeedTest 服务的 Docker 镜像,支持使用 SpeedTest 测试 ExpressVPN 的连接速度。Docker 镜像构建成功后,可以利用 Privoxy 与 Tor 在 ExpressVPN 的基础上,实现普通代理与匿名代理服务。

项目地址

构建镜像

Dockerfile 文件

Dockerfile 文件的内容如下,核心内容是安装 Privoxy、Tor、ExpressVPN,并指定 Privoxy 与 Tor 的监听端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
FROM debian:bullseye-slim

LABEL maintainer="benjamin@polkaned.net"

ENV ACTIVATION_CODE Code
ENV LOCATION smart
ARG APP=expressvpn_3.25.0.13-1_amd64.deb

RUN apt-get update && apt-get install -y --no-install-recommends \
wget curl apt-utils apt-transport-https dirmngr ca-certificates expect iproute2 procps libnm0 gnupg2 tor privoxy \
&& rm -rf /var/lib/apt/lists/* \
&& wget -q "https://www.expressvpn.works/clients/linux/${APP}" -O /tmp/${APP} \
&& dpkg -i /tmp/${APP} \
&& rm -rf /tmp/*.deb \
&& apt-get purge -y --auto-remove wget \
&& sed -i \
-e 's/#SocksPort 192.168.0.1:9100/SocksPort 0.0.0.0:9050/g' \
-e 's/#ControlPort 9051/ControlPort 9052/g' \
/etc/tor/torrc \
&& sed -i \
-e 's/listen-address\s*127.0.0.1:8118/listen-address 0.0.0.0:8118/g' \
/etc/privoxy/config

COPY entrypoint.sh /tmp/entrypoint.sh
COPY expressvpnActivate.sh /tmp/expressvpnActivate.sh

ENTRYPOINT ["/bin/bash", "/tmp/entrypoint.sh"]

Shell 脚本文件

entrypoint.sh 文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/bash

service tor start
service privoxy start

cp /etc/resolv.conf /tmp/resolv.conf
su -c 'umount /etc/resolv.conf'
cp /tmp/resolv.conf /etc/resolv.conf
sed -i 's/DAEMON_ARGS=.*/DAEMON_ARGS=""/' /etc/init.d/expressvpn
service expressvpn restart
/usr/bin/expect /tmp/expressvpnActivate.sh
expressvpn connect $SERVER
exec "$@"

expressvpnActivate.sh 文件的内容如下:

1
2
3
4
5
6
7
#!/usr/bin/expect
spawn expressvpn activate
expect "code:"
send "$env(ACTIVATION_CODE)\r"
expect "information."
send "n\r"
expect eof

构建 Docker 镜像

由于这里需要从官网下载 ExpressVPN 的安装包,因此构建 Docker 镜像时,必须保证可以科学上网,否则无法正常构建镜像。温馨提示,若无法提供科学上网的条件,可参考这里的方案来解决。

1
# docker build --pull --no-cache --rm --force-rm -f Dockerfile -t polkaned/privoxy-tor-expressvpn:latest .

运行容器

Docker 运行容器

  • {% your-activation-code %}:ExpressVPN 的激活码,例如 ACTIVATION_CODE=ABCD1EBGH2IJAL3MNOP4QRS
  • {% LOCATION/ALIAS/COUNTRY %}:ExpressVPN 的连接位置,例如 SERVER=jpyo,若为空值则默认使用 ExpressVPN 的智能位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker run \
--env=ACTIVATION_CODE={% your-activation-code %} \
--env=SERVER={% LOCATION/ALIAS/COUNTRY %} \
--cap-add=NET_ADMIN \
--device=/dev/net/tun \
--privileged \
--detach=true \
--tty=true \
-p 9050:9050 \
-p 9052:9052 \
-p 8118:8118 \
--name=expressvpn \
polkaned/privoxy-tor-expressvpn \
/bin/bash

Docker-Compose 运行容器

docker-compose.yml 文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.5"

services:
expressvpn:
container_name: expressvpn
image: polkaned/privoxy-tor-expressvpn:latest
privileged: true
restart: always
environment:
- ACTIVATION_CODE={% your-activation-code %}
- SERVER={% LOCATION/ALIAS/COUNTRY %}
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
ports:
- 9050:9050
- 9052:9052
- 8118:8118
tty: true
stdin_open: true
command: /bin/bash

若其他容器需要使用 ExpressVPN,那么可以参考以下配置内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: "3.5"

services:
expressvpn:
container_name: expressvpn
image: polkaned/privoxy-tor-expressvpn:latest
privileged: true
restart: always
environment:
- ACTIVATION_CODE={% your-activation-code %}
- SERVER={% LOCATION/ALIAS/COUNTRY %}
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
ports:
- 9050:9050
- 9052:9052
- 8118:8118
tty: true
stdin_open: true
command: /bin/bash

downloader:
image: example/downloader
container_name: downloader
network_mode: service:expressvpn
depends_on:
- expressvpn

通过 Docker-Compose 创建并启动 Docker 容器

1
2
3
4
5
# 创建并启动容器
# docker-compose up -d

# 查看容器的日志信息
# docker logs -f --tail 20 expressvpn

测试 Privoxy 与 Tor 代理是否可用

1
2
3
4
5
# 测试Privoxy
$ curl -I -x 127.0.0.1:8118 www.google.com

# 测试Tor
$ curl --socks5 127.0.0.1:9050 www.google.com

进阶配置

Privoxy 代理 Tor(可选)

若希望 Privoxy 代理 Tor,可以在 /etc/privoxy/config 配置文件的末尾添加以下内容:

1
forward-socks5 / 0.0.0.0:9050 .

限制请求来源的 IP(可选)

若希望限制访问 Privoxy 代理服务的 IP,即新增 IP 白名单,则可以在 /etc/privoxy/config 配置文件的末尾添加以下内容:

1
2
3
4
5
6
# 编辑配置文件,IP需要根据实际情况进行更改
# vim /etc/privoxy/config
permit-access 14.215.177.38/26

# 重启容器让配置变更生效
# docker restart expressvpn

挂载本地配置文件(可选)

1)启动 Docker 容器后,分别拷贝一份 Privoxy、Tor 的配置文件到宿主机的本地磁盘

1
2
3
4
5
6
7
# 创建宿主机本地的配置文件目录
# mkdir -p /usr/local/tor
# mkdir -p /usr/local/privoxy

# 拷贝容器里的配置文件到宿主机的本地磁盘
# docker cp expressvpn:/etc/tor/torrc /usr/local/tor/torrc
# docker cp expressvpn:/etc/privoxy/config /usr/local/privoxy/config

2)创建 Privoxy 的 user.action 配置文件,用于阻止 Privoxy 指向服务器本身的 IP 和域名,这里请替换为你自己真实服务器的 IP 和域名

1
2
3
4
5
# 创建文件
$ touch /usr/local/privoxy/user.action

# 写入以下内容到文件中
$ vim /usr/local/privoxy/user.action
1
2
{+block{block ip and domain which point to server itself}}
127.0.0.1

3)创建 Privoxy 的 user.filter 配置文件,用于存放 Privoxy 的过滤规则,暂时不需要填写任何内容

1
$ touch /usr/local/privoxy/user.filter

4)更改 docker-compose.yml 文件,添加数据卷的配置内容(如下所示)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: "3.5"

services:
expressvpn:
container_name: expressvpn
image: polkaned/privoxy-tor-expressvpn:latest
privileged: true
restart: always
environment:
- ACTIVATION_CODE={% your-activation-code %}
- SERVER={% LOCATION/ALIAS/COUNTRY %}
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
ports:
- 9050:9050
- 9052:9052
- 8118:8118
volumes:
- /usr/local/tor/torrc:/etc/privoxy/torrc
- /usr/local/privoxy/config:/etc/privoxy/config
- /usr/local/privoxy/user.action:/etc/privoxy/user.action
- /usr/local/privoxy/user.filter:/etc/privoxy/user.filter
tty: true
stdin_open: true
command: /bin/bash

VPN 管理

ExpressVPN 常用管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 优化ExpressVPN的配置
# docker exec -it expressvpn expressvpn protocol lightway_udp
# docker exec -it expressvpn expressvpn preferences set desktop_notifications false

# 查看ExpressVP的配置信息
# docker exec -it expressvpn expressvpn preferences

# 查看ExpressVPN的连接状态
# docker exec -it expressvpn expressvpn status

# 查看ExpressVPN的可连接地区
# docker exec -it expressvpn expressvpn list

# 连接VPN(智能连接)
# docker exec -it expressvpn expressvpn connect

# 连接VPN,并指定连接的地区
# docker exec -it expressvpn expressvpn connect jpyo

# 断开VPN连接
# docker exec -it expressvpn expressvpn disconnect

VPN 测速

ExpressVPN 使用 SpeedTest 测速

若希望测试 ExpressVPN 的连接速度,则可以安装 SpeedTest 来实现,更改后完整的 Dockerfile 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
FROM debian:bullseye-slim

LABEL maintainer="benjamin@polkaned.net"

ENV ACTIVATION_CODE Code
ENV LOCATION smart
ARG APP=expressvpn_3.18.1.0-1_amd64.deb

RUN apt-get update && apt-get install -y --no-install-recommends \
wget curl apt-utils apt-transport-https dirmngr ca-certificates expect iproute2 procps libnm0 gnupg2 tor privoxy \
&& rm -rf /var/lib/apt/lists/* \
&& wget -q "https://www.expressvpn.works/clients/linux/${APP}" -O /tmp/${APP} \
&& dpkg -i /tmp/${APP} \
&& rm -rf /tmp/*.deb \
&& apt-get purge -y --auto-remove wget \
&& sed -i \
-e 's/#SocksPort 192.168.0.1:9100/SocksPort 0.0.0.0:9050/g' \
-e 's/#ControlPort 9051/ControlPort 9052/g' \
/etc/tor/torrc \
&& sed -i \
-e 's/listen-address\s*127.0.0.1:8118/listen-address 0.0.0.0:8118/g' \
/etc/privoxy/config \
&& curl -s https://install.speedtest.net/app/cli/install.deb.sh | bash \
&& apt-get install speedtest

COPY entrypoint.sh /tmp/entrypoint.sh
COPY expressvpnActivate.sh /tmp/expressvpnActivate.sh

ENTRYPOINT ["/bin/bash", "/tmp/entrypoint.sh"]

使用命令行测试 ExpressVPN 的连接速度:

1
2
3
4
5
# 测速
# docker exec -it expressvpn speedtest

# 测速,并指定网速的显示单位
# docker exec -it expressvpn speedtest -u kB/s

SpeedTest 支持显示的网速单位如下:

1
2
3
4
Decimal prefix, bits per second:  bps, kbps, Mbps, Gbps
Decimal prefix, bytes per second: B/s, kB/s, MB/s, GB/s
Binary prefix, bits per second: kibps, Mibps, Gibps
Binary prefix, bytes per second: kiB/s, MiB/s, GiB/s

常见问题

ExpressVPN 版本更新

若日后希望更新 ExpressVPN 的版本,只需要执行以下两步操作即可:

  • 1)更改 Dockerfile 里 ExpressVPN 安装包的文件名
1
2
3
4
FROM debian:bullseye-slim
...
ARG APP=expressvpn_3.18.1.0-1_amd64.deb
...
  • 2)重新构建 Docker 镜像
1
# docker build --pull --no-cache --rm --force-rm -f Dockerfile -t polkaned/privoxy-tor-expressvpn:latest .

Chrome 浏览器使用 Privoxy 代理

若希望 Chrome 浏览器智能切换至 Docker + ExpressVPN + Privoxy/Tor 提供的代理服务(实现国内外流量分流功能),可以安装 SwitchyOmega 浏览器插件来实现,具体使用方式这里不再累述,更多资料可参考以下链接:

构建 Docker 镜像时无法科学上网

在上面的教程里,必须保证可以科学上网才能正常构建 Docker 镜像。特殊情况下,可能无法提供科学上网的条件,此时可以通过其他途径手动下载 ExpressVPN 最新版本的 Debian/Ubuntu 安装包,并将安装包重命名为 expressvpn_amd64.deb,然后更改上面的 Dockerfile 的内容(如下所示),这样就可以直接构建 Docker 镜像,不再需要依赖科学上网了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
FROM debian:bullseye-slim

LABEL maintainer="benjamin@polkaned.net"

ENV ACTIVATION_CODE Code
ENV LOCATION smart

COPY expressvpn_amd64.deb /tmp/expressvpn_amd64.deb
RUN dpkg -i /tmp/expressvpn_amd64.deb && rm -rf /tmp/expressvpn_amd64.deb

RUN apt-get update && apt-get install -y --no-install-recommends \
curl apt-utils apt-transport-https dirmngr ca-certificates expect iproute2 procps libnm0 gnupg2 tor privoxy \
&& rm -rf /var/lib/apt/lists/* \
&& sed -i \
-e 's/#SocksPort 192.168.0.1:9100/SocksPort 0.0.0.0:9050/g' \
-e 's/#ControlPort 9051/ControlPort 9052/g' \
/etc/tor/torrc \
&& sed -i \
-e 's/listen-address\s*127.0.0.1:8118/listen-address 0.0.0.0:8118/g' \
/etc/privoxy/config

COPY entrypoint.sh /tmp/entrypoint.sh
COPY expressvpnActivate.sh /tmp/expressvpnActivate.sh

ENTRYPOINT ["/bin/bash", "/tmp/entrypoint.sh"]

参考资料