diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 8288d34..a182822 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -4,9 +4,6 @@ services: image: wireadmin volumes: - ./src/:/app/ - ports: - - "4040:4040/udp" # Direct - - "4050:4050/udp" # Tor environment: - UI_PASSWORD=password - - WG_HOST=127.0.0.1 + - WG_HOST=192.168.1.102 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 038e23d..4635bc7 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -19,12 +19,10 @@ fi screen -dmS redis bash -c "redis-server --port 6479 --daemonize no --dir /data --appendonly yes" # Start Tor in the background -screen -dmS tor bash -c "tor -f /etc/tor/torrc" +screen -dmS tor bash -c "sleep 1; tor -f /etc/tor/torrc" # If WG_HOST exists, again export it as NEXT_PUBLIC_WG_HOST -if [ ! -z "$WG_HOST" ]; then - export NEXT_PUBLIC_WG_HOST=$WG_HOST -fi +export NEXT_PUBLIC_WG_HOST="$WG_HOST" # After 5 seconds, export the database to the WireGuard config file screen -dm bash -c "sleep 5; curl -s -o /dev/null http://127.0.0.1:3000/api/wireguard/regen" diff --git a/src/lib/schemas/WireGuard.ts b/src/lib/schemas/WireGuard.ts index 55aa865..0039e67 100644 --- a/src/lib/schemas/WireGuard.ts +++ b/src/lib/schemas/WireGuard.ts @@ -29,7 +29,7 @@ export const PortSchema = z message: 'Port must be a valid port number' }) -export const TypeSchema = z.enum([ 'default', 'tor' ]) +export const TypeSchema = z.enum([ 'direct', 'tor' ]) export const DnsSchema = z .string() diff --git a/src/lib/wireguard-utils.ts b/src/lib/wireguard-utils.ts index e6917cb..ed9b3a3 100644 --- a/src/lib/wireguard-utils.ts +++ b/src/lib/wireguard-utils.ts @@ -30,8 +30,9 @@ export function getServerConf(server: WgServer): string { type Peer = WgServer['peers'][0] -interface GenPeerConParams extends Peer { +interface GenPeerConParams extends Peer, Pick { serverAddress?: string + serverPublicKey: string port: number } @@ -40,12 +41,13 @@ export function getPeerConf(params: GenPeerConParams): string { '# Autogenerated by WireGuard UI (WireAdmin)', '[Interface]', `PrivateKey = ${params.privateKey}`, - `Address = ${params.allowedIps}/32`, + `Address = ${params.allowedIps}/24`, + `${params.dns ? `DNS = ${params.dns}` : 'OMIT'}`, '', '[Peer]', - `PublicKey = ${params.publicKey}`, + `PublicKey = ${params.serverPublicKey}`, `${params.preSharedKey ? `PresharedKey = ${params.preSharedKey}` : 'OMIT'}`, - `AllowedIPs = ${params.allowedIps}/32`, + `AllowedIPs = 0.0.0.0/0, ::/0`, `PersistentKeepalive = ${params.persistentKeepalive}`, `Endpoint = ${params.serverAddress || process.env.NEXT_PUBLIC_WG_HOST}:${params.port}`, ] diff --git a/src/lib/wireguard.ts b/src/lib/wireguard.ts index f9758f7..46bd984 100644 --- a/src/lib/wireguard.ts +++ b/src/lib/wireguard.ts @@ -16,7 +16,10 @@ export class WGServer { console.error('server could not be updated (reason: not exists)') return false } - await Shell.exec(`ip link set down dev wg${server.confId}`, true) + + await Shell.exec(`wg-quick down wg${server.confId}`, true) + await dropInterface(server.confId) + await this.update(id, { status: 'down' }) return true } @@ -27,8 +30,10 @@ export class WGServer { console.error('server could not be updated (reason: not exists)') return false } - await createInterface(server.confId, server.address) - await Shell.exec(`ip link set up dev wg${server.confId}`) + + await Shell.exec(`wg-quick down wg${server.confId}`, true) + await Shell.exec(`wg-quick up wg${server.confId}`) + await this.update(id, { status: 'up' }) return true } @@ -189,7 +194,12 @@ export class WGServer { console.error('generatePeerConfig: peer not found') return undefined } - return getPeerConf({ ...peer, port: server.listen }) + return getPeerConf({ + ...peer, + serverPublicKey: server.publicKey, + port: server.listen, + dns: server.dns + }) } } @@ -402,16 +412,14 @@ export async function generateWgServer(config: { }) // to ensure interface does not exists + await Shell.exec(`wg-quick down wg${confId}`, true) await dropInterface(confId) - await Shell.exec(`ip link set down dev wg${confId}`, true) - // create a interface - await createInterface(confId, config.address) + // await createInterface(confId, config.address) // restart WireGuard - await Shell.exec(`wg setconf wg${confId} ${CONFIG_PATH}`) - await Shell.exec(`ip link set up dev wg${confId}`) + await Shell.exec(`wg-quick up wg${confId}`) // return server id return uuid @@ -502,7 +510,7 @@ async function makeWgIptables(s: WgServer): Promise<{ up: string down: string }> { - const inet = Shell.exec('ip route | grep default | grep -oP "(?<=dev )[^ ]+"') + const inet = await Shell.exec('ip route list default | awk \'{print $5}\'') const wgAddress = `${s.address}/24` const wgInet = `wg${s.confId}` diff --git a/src/next.config.js b/src/next.config.js index 3e74393..fb1134c 100644 --- a/src/next.config.js +++ b/src/next.config.js @@ -9,7 +9,9 @@ function publicENV(ex = {}) { const nextConfig = { reactStrictMode: true, transpilePackages: [], - env: publicENV() + env: publicENV({ + NEXT_PUBLIC_WG_HOST: process.env.WG_HOST + }) } module.exports = nextConfig; diff --git a/src/pages/[serverId]/index.tsx b/src/pages/[serverId]/index.tsx index f80e0f5..e5dde60 100644 --- a/src/pages/[serverId]/index.tsx +++ b/src/pages/[serverId]/index.tsx @@ -190,6 +190,8 @@ export default function ServerPage(props: PageProps) { key={s.id} {...s} serverId={props.serverId} + serverPublicKey={data?.publicKey} + dns={data?.dns} listenPort={data?.listen} refreshTrigger={() => refresh()} /> @@ -214,8 +216,9 @@ export default function ServerPage(props: PageProps) { type Peer = WgServer['peers'][0] -interface ClientProps extends Peer { +interface ClientProps extends Peer, Pick { serverId: string + serverPublicKey: string listenPort: number refreshTrigger: () => void } @@ -229,7 +232,9 @@ function Client(props: ClientProps) { React.useEffect(() => { setConf(getPeerConf({ ...props, - port: props.listenPort + serverPublicKey: props.serverPublicKey, + port: props.listenPort, + dns: props.dns, })) console.log('conf', conf) }, [ props ]) @@ -254,12 +259,18 @@ function Client(props: ClientProps) { return ( -
-
- {props.name} +
+
+ {/* User Icon */} +
- {props.allowedIps} +
+ {props.name} +
+
+ {props.allowedIps} +
@@ -310,7 +321,7 @@ function ClientBaseButton(props: {
{ + for (const s of servers) { const CONFIG_PATH = path.join(WG_PATH, `wg${s.confId}.conf`) fs.writeFileSync(CONFIG_PATH, getServerConf(s), { mode: 0o600 }) - }) + await WGServer.start(s.id) + } return res .status(200) diff --git a/src/ui/Modal/CreateServerModal.tsx b/src/ui/Modal/CreateServerModal.tsx index 9215be3..bfa254d 100644 --- a/src/ui/Modal/CreateServerModal.tsx +++ b/src/ui/Modal/CreateServerModal.tsx @@ -24,7 +24,7 @@ const CreateServerModal = React.forwardRef< const innerRef = React.useRef(null) const [ form ] = Form.useForm() - const [ type, setType ] = React.useState<'default' | 'tor'>('default') + const [ type, setType ] = React.useState('direct') React.useImperativeHandle(ref, () => innerRef.current as SmartModalRef) @@ -206,4 +206,6 @@ const FormSchema = z.object({ mtu: MtuSchema }) +type ServerType = z.infer + type FormValues = z.infer