Skip to content

Commit bdc050e

Browse files
committed
Add Dockerfile
Signed-off-by: Neil Shen <overvenus@gmail.com>
1 parent 6694fdd commit bdc050e

8 files changed

Lines changed: 227 additions & 1 deletion

File tree

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_tools
2+
corplink-headless

Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Stage 1: Build
2+
FROM golang:1.24 AS builder
3+
4+
# Extract corplink-service
5+
RUN wget -q -O corplink.deb \
6+
https://oss-s3.ifeilian.com/linux/FeiLian_Linux_v2.0.9_r615_97b98b.deb && \
7+
dpkg-deb -x ./corplink.deb /
8+
9+
WORKDIR /app
10+
11+
COPY go.mod go.sum ./
12+
ENV GOPROXY=https://goproxy.cn
13+
RUN go mod download
14+
15+
COPY . .
16+
RUN CGO_ENABLED=0 go build .
17+
18+
# Stage 2: Final image
19+
FROM ubuntu:20.04
20+
21+
ENV CONTAINER=1
22+
23+
# Install socks5
24+
COPY --from=serjs/go-socks5-proxy /socks5 /usr/local/bin/socks5
25+
# Install corplink-headless
26+
RUN mkdir -p /opt/Corplink
27+
COPY --from=builder /app/corplink-headless /opt/Corplink
28+
# Install corplink-service
29+
COPY --from=builder /opt/Corplink/corplink-service /opt/Corplink/
30+
# Install services
31+
COPY ./scripts/install_service.sh /opt/Corplink
32+
RUN bash /opt/Corplink/install_service.sh && rm /opt/Corplink/install_service.sh
33+
COPY ./scripts/startup.sh /
34+
35+
WORKDIR /opt/Corplink
36+
USER root
37+
38+
ENV COMPANY_CODE=""
39+
40+
ENTRYPOINT ["/startup.sh"]

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build:
2+
docker build -t overvenus/corplink:latest .

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# corplink-headless
2+
3+
corplink-headless is a headless client for corplink VPN. It designed to run the official corplink VPN in a docker container.
4+
5+
## Usage
6+
7+
1. Run the container as a daemon.
8+
9+
```bash
10+
docker run -d \
11+
--name=corplink \
12+
--hostname=ubuntu \
13+
--device=/dev/net/tun \
14+
--cap-add=NET_ADMIN \
15+
--shm-size=512m \
16+
-p 8888:8118 \
17+
-p 1088:1080 \
18+
-e COMPANY_CODE="your_company" \
19+
overvenus/corplink:latest
20+
```
21+
22+
2. Configure corplink.
23+
24+
```bash
25+
# Scan QR code using Feilian App
26+
docker exec -it corplink-headless less -rf +F /var/log/corplink-headless/stdout.log
27+
# Quit less if it prints "login success, company code: xxx"
28+
```
29+
30+
3. Access corplink network via http proxy: localhost:8888 or socks5 proxy: localhost:1088.
31+
You can also route traffic to the container. The container will do SNAT for all traffic sent to it.
32+
33+
## Acknowledgments
34+
35+
* corplink-headless is inspired by [sleepymole/docker-corplink](https://github.com/sleepymole/docker-corplink).
36+
The Dockerfile and relevant scirpts are modified from the project.

main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package main
22

33
import (
44
"context"
5+
"errors"
56
"flag"
67
"log"
8+
"os"
79

810
"github.com/overvenus/corplink-headless/pkg/headless"
911
)
@@ -16,7 +18,12 @@ func main() {
1618
flag.Parse()
1719
err := func() error {
1820
if *companyCode == "" {
19-
log.Println("company-code is not be empty")
21+
// Get from env
22+
code := os.Getenv("COMPANY_CODE")
23+
if code == "" {
24+
return errors.New("company-code must not be empty")
25+
}
26+
*companyCode = code
2027
}
2128
token, err := headless.NewToken(*rpcConf)
2229
if err != nil {

pkg/headless/login.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ func (s *loginState) Execute(ctx context.Context, cli State) error {
237237
success, err1 = s.checkLoginToken(ctx, cli, token)
238238
if success {
239239
log.Printf("login success, company code: %s", cli.GetCompanyCode())
240+
fmt.Printf("login success, company code: %s\n", cli.GetCompanyCode())
240241
return nil
241242
}
242243
time.Sleep(time.Second)

scripts/install_service.sh

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Modified from https://github.com/sleepymole/docker-corplink
4+
5+
if [ -z "$CONTAINER" ]; then
6+
echo "CONTAINER is not set, it should be run in a docker container"
7+
exit 1
8+
fi
9+
10+
set -ex
11+
12+
apt-get update
13+
apt-get install -y \
14+
supervisor \
15+
privoxy \
16+
jq \
17+
iptables \
18+
iproute2 \
19+
net-tools \
20+
iputils-ping \
21+
less \
22+
ca-certificates && \
23+
rm -rf /var/lib/apt/lists/*
24+
25+
# corplink-service
26+
mkdir -p /var/log/corplink/
27+
cat <<EOF >/etc/supervisor/conf.d/corplink.conf
28+
[program:corplink]
29+
command=/opt/Corplink/corplink-service
30+
autostart=true
31+
autorestart=true
32+
stderr_logfile=/var/log/corplink/stderr.log
33+
stdout_logfile=/var/log/corplink/stdout.log
34+
priority=1
35+
startsecs=3
36+
EOF
37+
38+
# corplink-headless
39+
mkdir -p /var/log/corplink-headless/
40+
cat <<EOF >/etc/supervisor/conf.d/corplink-headless.conf
41+
[program:corplink-headless]
42+
command=/opt/Corplink/corplink-headless
43+
autostart=true
44+
autorestart=true
45+
stderr_logfile=/var/log/corplink-headless/stderr.log
46+
stdout_logfile=/var/log/corplink-headless/stdout.log
47+
priority=2
48+
EOF
49+
50+
# Privoxy
51+
mkdir -p /var/log/privoxy
52+
cat <<EOF >/etc/supervisor/conf.d/privoxy.conf
53+
[program:privoxy]
54+
command=/usr/sbin/privoxy --no-daemon /etc/privoxy/config
55+
autostart=true
56+
autorestart=true
57+
stderr_logfile=/var/log/privoxy/stderr.log
58+
stdout_logfile=/var/log/privoxy/stdout.log
59+
EOF
60+
sed -i '/^listen-address/d' /etc/privoxy/config
61+
echo 'listen-address 0.0.0.0:8118' >>/etc/privoxy/config
62+
63+
# Socks5 server
64+
mkdir -p /var/log/socks5/
65+
cat <<EOF >/etc/supervisor/conf.d/socks5.conf
66+
[program:socks5]
67+
command=/usr/local/bin/socks5
68+
autostart=true
69+
autorestart=true
70+
stderr_logfile=/var/log/socks5/stderr.log
71+
stdout_logfile=/var/log/socks5/stdout.log
72+
EOF
73+
74+
# Automatic fix dns
75+
cat <<EOF >/usr/local/bin/fixdns.sh
76+
#!/bin/bash
77+
set -x
78+
while true; do
79+
sleep 5
80+
dns=\$(jq -r '.DNS[0]' /opt/Corplink/vpn.conf 2>/dev/null)
81+
[ -z "\$dns" ] && continue
82+
grep -q "\$dns" /etc/resolv.conf && continue
83+
echo "nameserver \${dns}" >/etc/resolv.conf
84+
echo "nameserver 114.114.114.114" >>/etc/resolv.conf
85+
echo "nameserver 1.1.1.1" >>/etc/resolv.conf
86+
done
87+
EOF
88+
chmod +x /usr/local/bin/fixdns.sh
89+
mkdir -p /var/log/fixdns/
90+
cat <<EOF >/etc/supervisor/conf.d/fixdns.conf
91+
[program:fixdns]
92+
command=/usr/local/bin/fixdns.sh
93+
autostart=true
94+
autorestart=true
95+
stderr_logfile=/var/log/fixdns/stderr.log
96+
stdout_logfile=/var/log/fixdns/stdout.log
97+
EOF
98+
99+
# Fix ssh stuck at debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
100+
# See https://serverfault.com/a/670081
101+
cat <<EOF >/usr/local/bin/fixsshmtu.sh
102+
#!/bin/bash
103+
set -x
104+
while true; do
105+
sleep 10
106+
mtu=\$(cat /sys/class/net/utun/mtu 2>/dev/null)
107+
[[ "\$mtu" -eq 1200 ]] && continue
108+
ifconfig utun mtu 1200
109+
done
110+
EOF
111+
chmod +x /usr/local/bin/fixsshmtu.sh
112+
mkdir -p /var/log/fixsshmtu/
113+
cat <<EOF >/etc/supervisor/conf.d/fixsshmtu.conf
114+
[program:fixsshmtu]
115+
command=/usr/local/bin/fixsshmtu.sh
116+
autostart=true
117+
autorestart=true
118+
stderr_logfile=/var/log/fixsshmtu/stderr.log
119+
stdout_logfile=/var/log/fixsshmtu/stdout.log
120+
EOF

scripts/startup.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Modified from https://github.com/sleepymole/docker-corplink
4+
5+
if [ -z "$CONTAINER" ]; then
6+
echo "CONTAINER is not set, it should be run in a docker container"
7+
exit 1
8+
fi
9+
10+
set -ex
11+
12+
iptables -t nat -F
13+
iptables -t nat -A POSTROUTING -j MASQUERADE
14+
/usr/bin/supervisord 2>/dev/null || true
15+
16+
while true; do {
17+
sleep 86400;
18+
} done

0 commit comments

Comments
 (0)