This commit is contained in:
Shahrad Elahi 2023-09-27 10:31:52 +03:30
parent 4ff0187f97
commit 9bee66a095
8 changed files with 98 additions and 45 deletions

View File

@ -7,6 +7,9 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY --from=golang:1.20-alpine /usr/local/go/ /usr/local/go/
COPY --from=gogost/gost:3.0.0-rc8 /bin/gost /usr/local/bin/gost
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
RUN apk add -U --no-cache \
iproute2 iptables net-tools \
screen vim curl bash \

View File

@ -7,6 +7,9 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY --from=golang:1.20-alpine /usr/local/go/ /usr/local/go/
COPY --from=gogost/gost:3.0.0-rc8 /bin/gost /usr/local/bin/gost
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
RUN apk add -U --no-cache \
iproute2 iptables net-tools \
screen vim curl bash \

View File

@ -1,5 +1,5 @@
# This file is auto generated by the WireAdmin. Do not edit.
VirtualAddrNetwork 10.192.0.0/10
SOCKSPort 9055
ControlPort 9051
DNSPort 53530
TransPort 9040
DNSPort {{INET_ADDRESS}}:53530
TransPort {{INET_ADDRESS}}:9040

View File

@ -7,3 +7,6 @@ services:
environment:
- UI_PASSWORD=password
- WG_HOST=192.168.1.102
- TOR_SOCKS5PROXY=host.docker.internal:1080
extra_hosts:
- "host.docker.internal:host-gateway"

View File

@ -17,6 +17,32 @@ fi
mkdir -p /var/vlogs
# IP address of the container
inet_address="$(hostname -i | awk '{print $1}')"
sed -i "s/{{INET_ADDRESS}}/$inet_address/g" /etc/tor/torrc
# if /etc/tor/bridges was mounted, use those bridges
if [ "$TOR_USE_BRIDGES" = "true" ]; then
echo "Using bridges..."
tee -a /etc/tor/torrc <<EOF
# Using Bridges, obsf4
UseBridges 1
ClientTransportPlugin obfs4 exec /usr/local/bin/obfs4proxy managed
EOF
cat /etc/tor/bridges >>/etc/tor/torrc
fi
# Removing duplicated lines form /etc/tor/torrc file
awk '!seen[$0]++' /etc/tor/torrc >/tmp/torrc
mv /tmp/torrc /etc/tor/torrc
# any other environment variables that start with TOR_ are added to the torrc
# file
env | grep ^TOR_ | sed -e 's/TOR_//' -e 's/=/ /' >>/etc/tor/torrc
# Start Tor in the background
screen -L -Logfile /var/vlogs/tor -dmS tor bash -c "tor"
@ -24,6 +50,15 @@ screen -L -Logfile /var/vlogs/tor -dmS tor bash -c "tor"
screen -L -Logfile /var/vlogs/redis -dmS redis bash -c "redis-server --port 6479 --daemonize no --dir /data --appendonly yes"
# After 5 seconds, export the database to the WireGuard config file
bash -c "sleep 5; curl -s -o /dev/null http://127.0.0.1:3000/api/wireguard/regen"&
screen -dm bash -c "sleep 5; curl -s -o /dev/null http://127.0.0.1:3000/api/wireguard/regen"
echo -e "\n======================== Versions ========================"
echo -e "Alpine Version: \c" && cat /etc/alpine-release
echo -e "WireGuard Version: \c" && wg -v | head -n 1 | awk '{print $1,$2}'
echo -e "Tor Version: \c" && tor --version | head -n 1
echo -e "Obfs4proxy Version: \c" && obfs4proxy -version
echo -e "\n========================= Torrc ========================="
cat /etc/tor/torrc
echo -e "========================================================\n"
exec "$@"

View File

@ -1,33 +1,5 @@
import { WgServer } from "@lib/typings";
export function getServerConf(server: WgServer): string {
const lines = [
'# Autogenerated by WireGuard UI (WireAdmin)',
'[Interface]',
`PrivateKey = ${server.privateKey}`,
`Address = ${server.address}/24`,
`ListenPort = ${server.listen}`,
`${server.dns ? `DNS = ${server.dns}` : 'OMIT'}`,
'',
`${server.preUp ? `PreUp = ${server.preUp}` : 'OMIT'}`,
`${server.postUp ? `PostUp = ${server.postUp}` : 'OMIT'}`,
`${server.preDown ? `PreDown = ${server.preDown}` : 'OMIT'}`,
`${server.postDown ? `PostDown = ${server.postDown}` : 'OMIT'}`,
]
server.peers.forEach((peer, index) => {
lines.push('')
lines.push(`## ${peer.name || `Peer #${index + 1}`}`)
lines.push('[Peer]')
lines.push(`PublicKey = ${peer.publicKey}`)
lines.push(`${peer.preSharedKey ? `PresharedKey = ${peer.preSharedKey}` : 'OMIT'}`)
lines.push(`AllowedIPs = ${peer.allowedIps}/32`)
lines.push(`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`)
})
return lines
.filter((l) => l !== 'OMIT')
.join('\n')
}
type Peer = WgServer['peers'][0]
interface GenPeerConParams extends Peer, Pick<WgServer, 'dns'> {

View File

@ -6,7 +6,7 @@ import { WgKey, WgServer } from "@lib/typings";
import { client, WG_SEVER_PATH } from "@lib/redis";
import { dynaJoin, isJson } from "@lib/utils";
import deepmerge from "deepmerge";
import { getPeerConf, getServerConf } from "@lib/wireguard-utils";
import { getPeerConf } from "@lib/wireguard-utils";
import Network from "@lib/network";
export class WGServer {
@ -405,7 +405,7 @@ export async function generateWgServer(config: {
const CONFIG_PATH = path.join(WG_PATH, `wg${confId}.conf`)
// save server config to disk
await fs.writeFile(CONFIG_PATH, getServerConf(server), {
await fs.writeFile(CONFIG_PATH, await genServerConf(server), {
mode: 0o600,
})
@ -459,18 +459,21 @@ export async function findServer(id: string | undefined, hash?: string): Promise
undefined
}
async function makeWgIptables(s: WgServer): Promise<{ up: string, down: string }> {
export async function makeWgIptables(s: WgServer): Promise<{ up: string, down: string }> {
const inet = await Network.defaultInterface()
const inet_address = await Shell.exec(`hostname -i | awk '{print $1}'`)
const source = `${s.address}/24`
const wgInet = `wg${s.confId}`
const wg_inet = `wg${s.confId}`
if (s.type === 'direct') {
const up = dynaJoin([
`iptables -t nat -A POSTROUTING -s ${source} -o ${inet} -j MASQUERADE`,
`iptables -A INPUT -p udp -m udp --dport ${s.listen} -j ACCEPT`,
`iptables -A INPUT -p tcp -m tcp --dport ${s.listen} -j ACCEPT`,
`iptables -A FORWARD -i ${wgInet} -j ACCEPT`,
`iptables -A FORWARD -o ${wgInet} -j ACCEPT`,
`iptables -A FORWARD -i ${wg_inet} -j ACCEPT`,
`iptables -A FORWARD -o ${wg_inet} -j ACCEPT`,
]).join('; ')
return { up, down: up.replace(/ -A /g, ' -D ') }
}
@ -478,10 +481,10 @@ async function makeWgIptables(s: WgServer): Promise<{ up: string, down: string }
if (s.type === 'tor') {
const up = dynaJoin([
`iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT`,
`iptables -A INPUT -i ${wgInet} -s ${source} -m state --state NEW -j ACCEPT`,
`iptables -t nat -A PREROUTING -i ${wgInet} -p udp -s ${source} --dport 53 -j DNAT --to-destination 127.0.0.1:53530`,
`iptables -t nat -A PREROUTING -i ${wgInet} -p tcp -s ${source} -j DNAT --to-destination 127.0.0.1:9040`,
`iptables -t nat -A PREROUTING -i ${wgInet} -p udp -s ${source} -j DNAT --to-destination 127.0.0.1:9040`,
`iptables -A INPUT -i ${wg_inet} -s ${source} -m state --state NEW -j ACCEPT`,
`iptables -t nat -A PREROUTING -i ${wg_inet} -p udp -s ${source} --dport 53 -j DNAT --to-destination ${inet_address}:53530`,
`iptables -t nat -A PREROUTING -i ${wg_inet} -p tcp -s ${source} -j DNAT --to-destination ${inet_address}:9040`,
`iptables -t nat -A PREROUTING -i ${wg_inet} -p udp -s ${source} -j DNAT --to-destination ${inet_address}:9040`,
`iptables -t nat -A OUTPUT -o lo -j RETURN`,
`iptables -A OUTPUT -m conntrack --ctstate INVALID -j DROP`,
`iptables -A OUTPUT -m state --state INVALID -j DROP`,
@ -492,3 +495,38 @@ async function makeWgIptables(s: WgServer): Promise<{ up: string, down: string }
return { up: '', down: '' }
}
export async function genServerConf(server: WgServer): Promise<string> {
const iptables = await makeWgIptables(server)
server.postUp = iptables.up
server.postDown = iptables.down
const lines = [
'# Autogenerated by WireGuard UI (WireAdmin)',
'[Interface]',
`PrivateKey = ${server.privateKey}`,
`Address = ${server.address}/24`,
`ListenPort = ${server.listen}`,
`${server.dns ? `DNS = ${server.dns}` : 'OMIT'}`,
'',
`${server.preUp ? `PreUp = ${server.preUp}` : 'OMIT'}`,
`${server.postUp ? `PostUp = ${server.postUp}` : 'OMIT'}`,
`${server.preDown ? `PreDown = ${server.preDown}` : 'OMIT'}`,
`${server.postDown ? `PostDown = ${server.postDown}` : 'OMIT'}`,
]
server.peers.forEach((peer, index) => {
lines.push('')
lines.push(`## ${peer.name || `Peer #${index + 1}`}`)
lines.push('[Peer]')
lines.push(`PublicKey = ${peer.publicKey}`)
lines.push(`${peer.preSharedKey ? `PresharedKey = ${peer.preSharedKey}` : 'OMIT'}`)
lines.push(`AllowedIPs = ${peer.allowedIps}/32`)
lines.push(`${peer.persistentKeepalive ? `PersistentKeepalive = ${peer.persistentKeepalive}` : 'OMIT'}`)
})
return lines
.filter((l) => l !== 'OMIT')
.join('\n')
}

View File

@ -1,7 +1,6 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import safeServe from "@lib/safe-serve";
import { getServers, WGServer } from "@lib/wireguard";
import { getServerConf } from "@lib/wireguard-utils";
import { genServerConf, getServers, WGServer } from "@lib/wireguard";
import fs from "fs";
import path from "path";
import { WG_PATH } from "@lib/constants";
@ -19,7 +18,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
for (const s of servers) {
const CONFIG_PATH = path.join(WG_PATH, `wg${s.confId}.conf`)
fs.writeFileSync(CONFIG_PATH, getServerConf(s), { mode: 0o600 })
fs.writeFileSync(CONFIG_PATH, await genServerConf(s), { mode: 0o600 })
await WGServer.start(s.id)
}