Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9368b857e8 | |||
| 0f663df7f6 | |||
| 68fde7d165 | |||
| 501a784264 | |||
| 629c184195 | |||
| 76b8818a33 | |||
| 6c52301a64 | |||
| be26db63ca | |||
| 962bfa213f | |||
| ee00e5c914 | |||
| 6343213538 | |||
| 187bdc0836 | |||
| f2520f0481 | |||
| 5e9a73645b | |||
| 783fa3286c | |||
| 77b4f9db65 | |||
| 0f6f07161b | |||
| d75a836de9 |
+23
-1
@@ -5,7 +5,29 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [15.1.0] - 2025-07-01
|
||||
|
||||
## Added
|
||||
|
||||
- Added Ukrainian language (#1906)
|
||||
- Add French language (#1924)
|
||||
- docs for caddy example (#1939)
|
||||
- add docs on how to add/update translation (be26db6)
|
||||
- Add german translations (#1889)
|
||||
- feat: Add Traditional Chinese (zh-HK) i18n Support (#1988)
|
||||
- Add Chinese Simplified (#1990)
|
||||
- Add option to disable ipv6 (#1951)
|
||||
|
||||
## Fixed
|
||||
|
||||
- Updated container launch commands (#1989)
|
||||
- update screenshot (962bfa2)
|
||||
|
||||
## Changed
|
||||
|
||||
- Updated dependencies
|
||||
|
||||
## [15.0.0] - 2025-05-28
|
||||
|
||||
We're super excited to announce v15!
|
||||
This update is an entire rewrite to make it even easier to set up your own VPN.
|
||||
|
||||
@@ -54,6 +54,7 @@ ENV PORT=51821
|
||||
ENV HOST=0.0.0.0
|
||||
ENV INSECURE=false
|
||||
ENV INIT_ENABLED=false
|
||||
ENV DISABLE_IPV6=false
|
||||
|
||||
LABEL org.opencontainers.image.source=https://github.com/wg-easy/wg-easy
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ ENV PORT=51821
|
||||
ENV HOST=0.0.0.0
|
||||
ENV INSECURE=true
|
||||
ENV INIT_ENABLED=false
|
||||
ENV DISABLE_IPV6=false
|
||||
|
||||
# Install Dependencies
|
||||
COPY src/package.json src/pnpm-lock.yaml ./
|
||||
|
||||
@@ -12,7 +12,7 @@ You have found the easiest way to install & manage WireGuard on any Linux host!
|
||||
<!-- TOOD: update screenshot -->
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/screenshot.png" width="802" />
|
||||
<img src="./assets/screenshot.png" width="802" alt="wg-easy Screenshot" />
|
||||
</p>
|
||||
|
||||
## Features
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 185 KiB |
@@ -1,44 +0,0 @@
|
||||
volumes:
|
||||
etc_wireguard:
|
||||
|
||||
services:
|
||||
wg-easy:
|
||||
#environment:
|
||||
# Optional:
|
||||
# - PORT=51821
|
||||
# - HOST=0.0.0.0
|
||||
# - INSECURE=false
|
||||
|
||||
image: ghcr.io/wg-easy/wg-easy:15
|
||||
container_name: wg-easy
|
||||
networks:
|
||||
wg:
|
||||
ipv4_address: 10.42.42.42
|
||||
ipv6_address: fdcc:ad94:bacf:61a3::2a
|
||||
volumes:
|
||||
- etc_wireguard:/etc/wireguard
|
||||
- /lib/modules:/lib/modules:ro
|
||||
ports:
|
||||
- "51820:51820/udp"
|
||||
- "51821:51821/tcp"
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
# - NET_RAW # ⚠️ Uncomment if using Podman Compose
|
||||
sysctls:
|
||||
- net.ipv4.ip_forward=1
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
- net.ipv6.conf.all.disable_ipv6=0
|
||||
- net.ipv6.conf.all.forwarding=1
|
||||
- net.ipv6.conf.default.forwarding=1
|
||||
|
||||
networks:
|
||||
wg:
|
||||
driver: bridge
|
||||
enable_ipv6: true
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.42.42.0/24
|
||||
- subnet: fdcc:ad94:bacf:61a3::/64
|
||||
+24
-25
@@ -3,35 +3,21 @@ volumes:
|
||||
|
||||
services:
|
||||
wg-easy:
|
||||
environment:
|
||||
# Change Language:
|
||||
# (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, ko, vi, nl, is, pt, chs, cht, it, th, hi)
|
||||
- LANG=de
|
||||
# ⚠️ Required:
|
||||
# Change this to your host's public address
|
||||
- WG_HOST=raspberrypi.local
|
||||
#environment:
|
||||
# Optional:
|
||||
# - PORT=51821
|
||||
# - HOST=0.0.0.0
|
||||
# - INSECURE=false
|
||||
|
||||
# Optional:
|
||||
# - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG # (needs double $$, hash of 'foobar123'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash)
|
||||
# - PORT=51821
|
||||
# - WG_PORT=51820
|
||||
# - WG_CONFIG_PORT=92820
|
||||
# - WG_DEFAULT_ADDRESS=10.8.0.x
|
||||
# - WG_DEFAULT_DNS=1.1.1.1
|
||||
# - WG_MTU=1420
|
||||
# - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24
|
||||
# - WG_PERSISTENT_KEEPALIVE=25
|
||||
# - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt
|
||||
# - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt
|
||||
# - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt
|
||||
# - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt
|
||||
# - UI_TRAFFIC_STATS=true
|
||||
# - UI_CHART_TYPE=0 # (0 Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart)
|
||||
|
||||
image: ghcr.io/wg-easy/wg-easy:14
|
||||
image: ghcr.io/wg-easy/wg-easy:15
|
||||
container_name: wg-easy
|
||||
networks:
|
||||
wg:
|
||||
ipv4_address: 10.42.42.42
|
||||
ipv6_address: fdcc:ad94:bacf:61a3::2a
|
||||
volumes:
|
||||
- etc_wireguard:/etc/wireguard
|
||||
- /lib/modules:/lib/modules:ro
|
||||
ports:
|
||||
- "51820:51820/udp"
|
||||
- "51821:51821/tcp"
|
||||
@@ -43,3 +29,16 @@ services:
|
||||
sysctls:
|
||||
- net.ipv4.ip_forward=1
|
||||
- net.ipv4.conf.all.src_valid_mark=1
|
||||
- net.ipv6.conf.all.disable_ipv6=0
|
||||
- net.ipv6.conf.all.forwarding=1
|
||||
- net.ipv6.conf.default.forwarding=1
|
||||
|
||||
networks:
|
||||
wg:
|
||||
driver: bridge
|
||||
enable_ipv6: true
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.42.42.0/24
|
||||
- subnet: fdcc:ad94:bacf:61a3::/64
|
||||
|
||||
@@ -4,8 +4,19 @@ title: Optional Configuration
|
||||
|
||||
You can set these environment variables to configure the container. They are not required, but can be useful in some cases.
|
||||
|
||||
| Env | Default | Example | Description |
|
||||
| ---------- | --------- | ----------- | ------------------------------ |
|
||||
| `PORT` | `51821` | `6789` | TCP port for Web UI. |
|
||||
| `HOST` | `0.0.0.0` | `localhost` | IP address web UI binds to. |
|
||||
| `INSECURE` | `false` | `true` | If access over http is allowed |
|
||||
| Env | Default | Example | Description |
|
||||
| -------------- | --------- | ----------- | ---------------------------------- |
|
||||
| `PORT` | `51821` | `6789` | TCP port for Web UI. |
|
||||
| `HOST` | `0.0.0.0` | `localhost` | IP address web UI binds to. |
|
||||
| `INSECURE` | `false` | `true` | If access over http is allowed |
|
||||
| `DISABLE_IPV6` | `false` | `true` | If IPv6 support should be disabled |
|
||||
|
||||
/// note | IPv6 Caveats
|
||||
|
||||
Disabling IPv6 will disable the creation of the default IPv6 firewall rules and won't add a IPv6 address to the interface and clients.
|
||||
|
||||
You will however still see a IPv6 address in the Web UI, but it won't be used.
|
||||
|
||||
This option can be removed in the future, as more devices support IPv6.
|
||||
|
||||
///
|
||||
|
||||
@@ -6,22 +6,24 @@ This guide will help you migrate from `v14` to version `v15` of `wg-easy`.
|
||||
|
||||
## Changes
|
||||
|
||||
- This is a complete rewrite of the `wg-easy` project. Therefore the configuration files and the way you interact with the project have changed.
|
||||
- This is a complete rewrite of the `wg-easy` project, therefore the configuration files and the way you interact with the project have changed.
|
||||
- If you use armv6, you unfortunately won't be able to migrate to `v15`.
|
||||
- If you are connecting to the web ui via HTTP, you need to set the `INSECURE` environment variable to `true` in the new container.
|
||||
- If you are connecting to the Web UI via HTTP, you need to set the `INSECURE` environment variable to `true` in the new container.
|
||||
|
||||
## Migration
|
||||
|
||||
### Backup
|
||||
|
||||
Before you start the migration, make sure to backup your existing configuration files.
|
||||
Before you start the migration, make sure to back up your existing configuration files.
|
||||
|
||||
Go into the Web Ui and click the Backup button, this should download a `wg0.json` file.
|
||||
Go into the Web UI and click the Backup button, this should download a `wg0.json` file.
|
||||
|
||||
Or download the `wg0.json` file from your container volume to your pc.
|
||||
|
||||
You will need this file for the migration
|
||||
|
||||
You will also need to back up the old environment variables you set for the container, as they will not be automatically migrated.
|
||||
|
||||
### Remove old container
|
||||
|
||||
1. Stop the running container
|
||||
@@ -32,10 +34,10 @@ If you are using `docker run`
|
||||
docker stop wg-easy
|
||||
```
|
||||
|
||||
If you are using `docker-compose`
|
||||
If you are using `docker compose`
|
||||
|
||||
```shell
|
||||
docker-compose down
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Start new container
|
||||
@@ -47,6 +49,10 @@ In the setup wizard, select that you already have a configuration file and uploa
|
||||
[docs-getting-started]: ../../getting-started.md
|
||||
[docs-examples]: ../../examples/tutorials/basic-installation.md
|
||||
|
||||
### Environment Variables
|
||||
|
||||
v15 does not use the same environment variables as v14, most of them have been moved to the Admin Panel in the Web UI.
|
||||
|
||||
### Done
|
||||
|
||||
You have now successfully migrated to `v15` of `wg-easy`.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Translation
|
||||
---
|
||||
|
||||
This project supports multiple languages. If you would like to contribute a translation, please follow these steps:
|
||||
|
||||
## Add new Translation
|
||||
|
||||
Create a new file in `src/i18n/locales`. Name it `<locale_code>.json` (e.g. `fr.json` for French).
|
||||
|
||||
Import and add the newly created file in `src/i18n/i18n.config.ts`.
|
||||
|
||||
Add your language in the `src/nuxt.config.ts` file. You have to specify code, language and name.
|
||||
|
||||
`code` is the name of the translation file without the extension (e.g. `fr` for `fr.json`).
|
||||
|
||||
`language` is the BCP 47 language tag with region (e.g. `fr-FR` for French). See [www.lingoes.net](http://www.lingoes.net/en/translator/langcode.htm) for a list of language codes.
|
||||
|
||||
`name` is the display name of the language (e.g. `Français` for French).
|
||||
|
||||
## Update existing Translation
|
||||
|
||||
If you need to update an existing translation, simply edit the corresponding `<locale_code>.json` file in `src/i18n/locales`.
|
||||
|
||||
## Contribute changes
|
||||
|
||||
See [Pull Requests](./issues-and-pull-requests.md#pull-requests) on how to contribute your translation.
|
||||
@@ -33,7 +33,7 @@ Follow the Docs here: <https://docs.docker.com/engine/install/> and install Dock
|
||||
|
||||
```shell
|
||||
cd /etc/docker/containers/wg-easy
|
||||
sudo docker-compose up -d
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
## Setup Firewall
|
||||
@@ -56,8 +56,8 @@ To update `wg-easy` to the latest version, run:
|
||||
|
||||
```shell
|
||||
cd /etc/docker/containers/wg-easy
|
||||
sudo docker-compose pull
|
||||
sudo docker-compose up -d
|
||||
sudo docker compose pull
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
## Auto Update
|
||||
|
||||
@@ -2,8 +2,101 @@
|
||||
title: Caddy
|
||||
---
|
||||
|
||||
It seems like the Docs on how to setup Caddy are not available yet.
|
||||
/// note | Opinionated
|
||||
|
||||
Feel free to create a PR and add them here.
|
||||
This guide is opinionated. If you use other conventions or folder layouts, feel free to change the commands and paths.
|
||||
///
|
||||
|
||||
<!-- TODO -->
|
||||
We're using [Caddy](https://caddyserver.com/) here as reserve proxy to serve `wg-easy` on [https://wg-easy.example.com](https://wg-easy.example.com) via TLS.
|
||||
|
||||
## Create a docker composition for `caddy`
|
||||
|
||||
```txt
|
||||
.
|
||||
├── compose.yml
|
||||
└── Caddyfile
|
||||
|
||||
1 directory, 2 files
|
||||
```
|
||||
|
||||
```yaml
|
||||
# compose.yml
|
||||
|
||||
services:
|
||||
caddy:
|
||||
container_name: caddy
|
||||
image: caddy:2.10.0-alpine
|
||||
# publish everything you deem necessary
|
||||
ports:
|
||||
- '80:80/tcp'
|
||||
- '443:443/tcp'
|
||||
- '443:443/udp'
|
||||
networks:
|
||||
- caddy
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- './Caddyfile:/etc/caddy/Caddyfile:ro'
|
||||
- config:/config
|
||||
- data:/data
|
||||
|
||||
networks:
|
||||
caddy:
|
||||
name: caddy
|
||||
|
||||
volumes:
|
||||
config:
|
||||
data:
|
||||
```
|
||||
|
||||
```txt
|
||||
# Caddyfile
|
||||
|
||||
{
|
||||
# setup your email address
|
||||
email mail@example.com
|
||||
}
|
||||
|
||||
wg-easy.example.com {
|
||||
# since the container will share the network with wg-easy
|
||||
# we can use the proper container name
|
||||
reverse_proxy wg-easy:80
|
||||
tls internal
|
||||
}
|
||||
```
|
||||
|
||||
...and start it with:
|
||||
|
||||
```shell
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
## Adapt the docker composition of `wg-easy`
|
||||
|
||||
```yaml
|
||||
services:
|
||||
wg-easy:
|
||||
# sync container name and port according to Caddyfile
|
||||
container_name: wg-easy
|
||||
environment:
|
||||
- PORT=80
|
||||
# no need to publish the HTTP server anymore
|
||||
ports:
|
||||
- "51820:51820/udp"
|
||||
# add to caddy network
|
||||
networks:
|
||||
caddy:
|
||||
...
|
||||
|
||||
networks:
|
||||
caddy:
|
||||
external: true
|
||||
...
|
||||
```
|
||||
|
||||
...and restart it with:
|
||||
|
||||
```shell
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
You can now access `wg-easy` at [https://wg-easy.example.com](https://wg-easy.example.com) and start the setup.
|
||||
|
||||
@@ -141,7 +141,7 @@ sudo docker network create traefik
|
||||
## Start traefik
|
||||
|
||||
```shell
|
||||
sudo docker-compose up -d
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
You can no access the Traefik dashboard at `https://traefik.$example.com$` with the credentials you set in `traefik_dynamic.yml`.
|
||||
@@ -178,7 +178,7 @@ networks:
|
||||
|
||||
```shell
|
||||
cd /etc/docker/containers/wg-easy
|
||||
sudo docker-compose up -d
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
You can now access `wg-easy` at `https://wg-easy.$example.com$` and start the setup.
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@
|
||||
"format:check:docs": "prettier --check docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.3"
|
||||
"prettier": "^3.6.2"
|
||||
},
|
||||
"packageManager": "pnpm@10.11.0"
|
||||
"packageManager": "pnpm@10.12.4"
|
||||
}
|
||||
|
||||
Generated
+5
-5
@@ -9,16 +9,16 @@ importers:
|
||||
.:
|
||||
devDependencies:
|
||||
prettier:
|
||||
specifier: ^3.5.3
|
||||
version: 3.5.3
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
|
||||
packages:
|
||||
|
||||
prettier@3.5.3:
|
||||
resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
|
||||
prettier@3.6.2:
|
||||
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
snapshots:
|
||||
|
||||
prettier@3.5.3: {}
|
||||
prettier@3.6.2: {}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import en from './locales/en.json';
|
||||
import uk from './locales/uk.json';
|
||||
import fr from './locales/fr.json';
|
||||
import de from './locales/de.json';
|
||||
import zhhk from './locales/zh-HK.json';
|
||||
import zhcn from './locales/zh-CN.json';
|
||||
|
||||
export default defineI18nConfig(() => ({
|
||||
legacy: false,
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
en,
|
||||
uk,
|
||||
fr,
|
||||
de,
|
||||
'zh-HK': zhhk,
|
||||
'zh-CN': zhcn,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Konto",
|
||||
"clients": "Clients",
|
||||
"admin": {
|
||||
"panel": "Admin-Konsole",
|
||||
"general": "Allgemein",
|
||||
"config": "Konfiguration",
|
||||
"interface": "Oberfläche",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "Email"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Aktuelles Passwort",
|
||||
"enable2fa": "Zwei-Faktor-Authentifizierunng aktivieren",
|
||||
"enable2faDesc": "Scannen Sie den QR-Code mit ihrer Authentifizierungs-App oder geben Sie den Schlüssel manuell ein.",
|
||||
"2faKey": "TOTP-Schlüssel",
|
||||
"2faCodeDesc": "Geben Sie den Code aus Ihrer Authentifizierungs-App ein.",
|
||||
"disable2fa": "Zwei-Faktor-Authentifizierung deaktivieren",
|
||||
"disable2faDesc": "Geben Sie Ihr Passwort ein, um die Zwei-Faktor-Authentifizierung zu deaktivieren."
|
||||
},
|
||||
"general": {
|
||||
"name": "Name",
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"newPassword": "Neues Passwort",
|
||||
"updatePassword": "Passwort aktualisieren",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Erlaubte IP-Adressen",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Dauerhaftes Keepalive",
|
||||
"logout": "Abmelden",
|
||||
"continue": "Weiter",
|
||||
"host": "Host",
|
||||
"port": "Port",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"confirmPassword": "Passwort bestätigen",
|
||||
"loading": "Laden...",
|
||||
"2fa": "Zwei-Faktor-Authentifizierung",
|
||||
"2faCode": "TOTP-Code"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Willkommen zur Ersteinrichtung von wg-easy",
|
||||
"welcomeDesc": "Das ist der einfachste Weg, um Wireguard auf jedem Linux-Server zu installieren und zu betreiben.",
|
||||
"existingSetup": "Haben Sie eine bestehende Einrichtung?",
|
||||
"createAdminDesc": "Bitte geben Sie zuerst einen Admin-Benutzernamen sowie ein starkes, sicheres Passwort ein. Diese Anmeldedaten benötigen Sie, um sich im Admin-Panel anzumelden.",
|
||||
"setupConfigDesc": "Bitte geben Sie die Host- und Portinformationen ein. Diese werden für die Client-Konfiguration verwendet, wenn Sie WireGuard auf Ihren Geräten einrichten.",
|
||||
"setupMigrationDesc": "Bitte halten Sie die Sicherungsdatei bereit, wenn Sie Ihre Daten von Ihrer vorherigen wg-easy Version auf ihre neue Einrichtung migrieren möchten.",
|
||||
"upload": "Hochladen",
|
||||
"migration": "Sicherung wiederherstellen:",
|
||||
"createAccount": "Konto erstellen",
|
||||
"successful": "Einrichtung erfolgreich",
|
||||
"hostDesc": "Öffentlicher Hostname mit dem sich die Clients verbinden",
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden und auf dem Wireguard läuft"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Es ist ein neue Aktualisierung verfügbar!",
|
||||
"update": "Aktualisieren"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Dunkles Thema",
|
||||
"light": "Helles Thema",
|
||||
"system": "System-Thema"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Statistiken ein-/ausblenden",
|
||||
"donate": "Spenden"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Anmelden",
|
||||
"rememberMe": "Angemeldet bleiben",
|
||||
"rememberMeDesc": "Bleiben Sie auch nach dem Schließen des Browsers angemeldet",
|
||||
"insecure": "Sie können sich nicht über eine unsichere Verbindung anmelden. Bitte benutzen Sie HTTPS.",
|
||||
"2faRequired": "Zwei-Faktor-Authentifizierung wird benötigt",
|
||||
"2faWrong": "Zwei-Faktor-Authentifizierung ist fehlgeschlagen"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Es gibt noch keine Clients.",
|
||||
"newShort": "Neu",
|
||||
"sort": "Sortieren",
|
||||
"create": "Client erstellen",
|
||||
"created": "Client wurde erstellt",
|
||||
"new": "Neuer client",
|
||||
"name": "Name",
|
||||
"expireDate": "Ablaufdatum",
|
||||
"expireDateDesc": "Datum, an dem der Client deaktiviert wird. Leer lassen, damit dies nie passiert.",
|
||||
"deleteClient": "Client löschen",
|
||||
"deleteDialog1": "Sind Sie sicher, dass Sie diesen Client löschen wollen",
|
||||
"deleteDialog2": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||
"enabled": "Aktiviert",
|
||||
"address": "Adresse",
|
||||
"serverAllowedIps": "serverseitig erlaubte IP-Adressen",
|
||||
"otlDesc": "Einen kurzen Einmal-Link erzeugen",
|
||||
"permanent": "Dauerhaft",
|
||||
"createdOn": "Angelegt am ",
|
||||
"lastSeen": "Zuletzt verbunden am ",
|
||||
"totalDownload": "Gesamt-Download: ",
|
||||
"totalUpload": "Gesamt-Upload: ",
|
||||
"newClient": "Neuer Client",
|
||||
"disableClient": "Client deaktivieren",
|
||||
"enableClient": "Client aktivieren",
|
||||
"noPrivKey": "Dieser Client hat keinen bekannten privaten Schlüssel, weshalb keine Konfiguration angelegt werden kann.",
|
||||
"showQR": "QR-Code anzeigen",
|
||||
"downloadConfig": "Konfiguration herunterladen",
|
||||
"allowedIpsDesc": "Welche IP-Adressen durch das VPN geleitet werden (überschreibt die globale Konfiguration)",
|
||||
"serverAllowedIpsDesc": "Welche IP-Adressen der Server zum Client leiten wird",
|
||||
"mtuDesc": "Setzt die maximale Übertragungsgröße (Paketgröße) für den VPN-Tunnel",
|
||||
"persistentKeepaliveDesc": "Legt das Intervall (in Sekunden) für Keepalive-Pakete fest. 0 deaktiviert es",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks funktionieren nur mit wg-quick",
|
||||
"hooksLeaveEmpty": "Nur für wg-quick. Sonst leer lassen",
|
||||
"dnsDesc": "DNS-Server, den die Clients benutzen (überschreibt die globale Konfiguration)"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Ändern",
|
||||
"cancel": "Abbrechen",
|
||||
"create": "Erstellen"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Erfolg",
|
||||
"saved": "Gespeichert",
|
||||
"error": "Fehler"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Aktionen",
|
||||
"save": "Speichern",
|
||||
"revert": "Rückgängig machen",
|
||||
"sectionGeneral": "Allgemein",
|
||||
"sectionAdvanced": "Erweitert",
|
||||
"noItems": "Keine Einträge",
|
||||
"nullNoItems": "Keine Einträge. Die globale Konfiguration wird benutzt",
|
||||
"add": "Hinzufügen"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Sitzungszeitüberschreitung",
|
||||
"sessionTimeoutDesc": "Sitzungsdauer für \"Angemeldet bleiben\" (Sekunden)",
|
||||
"metrics": "Statistiken",
|
||||
"metricsPassword": "Passwort",
|
||||
"metricsPasswordDesc": "Bearer-Passwort für den Statistik-Endpunkt (Passwort oder Argon2-Hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Pfad zu den Statistiken als JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Pfad zu den Prometheus-Statistiken"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Verbindung",
|
||||
"hostDesc": "Öffentlicher Hostname mit dem sich die Clients verbinden (überschreibt die Konfiguration)",
|
||||
"portDesc": "Öffentlicher UDP-Port an dem sich die Clients verbinden (überschreibt die Konfiguration, vermutlich wollen Sie ebenfalls den Port der Weboberfläche ändern)",
|
||||
"allowedIpsDesc": "Erlaubte IP-Adressen, die die Clients nutzen werden (Globale Konfiguration)",
|
||||
"dnsDesc": "DNS-Server, den die Clients nutzen werden (Globale Konfiguration)",
|
||||
"mtuDesc": "MTU, den die Clients benutzen werden (nur für neue Clients)",
|
||||
"persistentKeepaliveDesc": "Intervall in Sekunden, in dem Keepalive-Packete an den Server gesendet werden. 0 = deaktiviert (nur für neue Clients)",
|
||||
"suggest": "Vorschlagen",
|
||||
"suggestDesc": "Wählen Sie eine IP-Adresse oder einen Hostnamen für das Host-Feld aus"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR wurde geändert",
|
||||
"device": "Gerät",
|
||||
"deviceDesc": "Ethernet-Gerät, durch das der Wireguard-Datenverkehr geleitet werden soll",
|
||||
"mtuDesc": "MTU, den WireGuard benutzen wird",
|
||||
"portDesc": "UDP Port, auf dem WireGuard lauschen wird (Sie wollen wahrscheinlich auch den Config-Port ändern)",
|
||||
"changeCidr": "CIDR ändern",
|
||||
"restart": "Interface neu starten",
|
||||
"restartDesc": "Das WireGuard-Interface neu starten",
|
||||
"restartWarn": "Sind Sie sicher, dass Sie das Interface neu starten wollen? Dies wird die Verbindungen aller Clients trennen.",
|
||||
"restartSuccess": "Interface neu gestartet"
|
||||
},
|
||||
"introText": "Willkommen in der Admin-Konsole.\n\nHier können Sie die allgemeinen Einstellungen, die Konfiguration, die Schnittstelleneinstellungen und die Hooks verwalten.\n\nBeginnen Sie, indem Sie einen der Bereiche in der Seitenleiste auswählen."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} ist erforderlich",
|
||||
"validNumber": "{0} muss eine Zahl sein",
|
||||
"validString": "{0} muss eine Zeichenkette sein",
|
||||
"validBoolean": "{0} muss ein Wahrheitswert sein",
|
||||
"validArray": "{0} muss eine Liste sein",
|
||||
"stringMin": "{0} muss mindestens {1} Zeichen lang sein",
|
||||
"numberMin": "{0} muss mindestens {1} sein"
|
||||
},
|
||||
"client": {
|
||||
"id": "Client-ID",
|
||||
"name": "Name",
|
||||
"expiresAt": "Läuft ab am",
|
||||
"address4": "IPv4-Adresse",
|
||||
"address6": "IPv6-Adresse",
|
||||
"serverAllowedIps": "serverseitig erlaubte IP-Adressen"
|
||||
},
|
||||
"user": {
|
||||
"username": "Benutzername",
|
||||
"password": "Passwort",
|
||||
"remember": "Merken",
|
||||
"name": "Name",
|
||||
"email": "Email",
|
||||
"emailInvalid": "Die Email-Adresse muss valide sein",
|
||||
"passwordMatch": "Die Passwörter müssen übereinstimmen",
|
||||
"totpEnable": "TOTP aktivieren",
|
||||
"totpEnableTrue": "\"TOTP aktivieren\" muss ausgewählt sein",
|
||||
"totpCode": "TOTP-Code"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Host"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Sitzungszeitüberschreitung",
|
||||
"metricsEnabled": "Statistiken",
|
||||
"metricsPassword": "Passwort für Statistiken"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Geräte",
|
||||
"cidrValid": "CIDR muss valide sein"
|
||||
},
|
||||
"otl": "Einmal-Link",
|
||||
"stringMalformed": "Zeichenkette ist fehlerhaft",
|
||||
"body": "Body muss ein gültiges Objekt sein",
|
||||
"hook": "Hook",
|
||||
"enabled": "Aktiviert",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Dauerhaftes Keepalive",
|
||||
"address": "IP-Adresse",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Erlaubte IP-Adressen",
|
||||
"file": "Datei"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Compte",
|
||||
"clients": "Clients",
|
||||
"admin": {
|
||||
"panel": "Panel Admin",
|
||||
"general": "Général",
|
||||
"config": "Config",
|
||||
"interface": "Interface",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "E-Mail"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Mot de passe actuel",
|
||||
"enable2fa": "Activer l'authentification à double facteur",
|
||||
"enable2faDesc": "Scannez le code QR avec votre application d'authentification ou saisissez la clé manuellement.",
|
||||
"2faKey": "Clé TOTP",
|
||||
"2faCodeDesc": "Saisissez le code de votre application d'authentification.",
|
||||
"disable2fa": "Désactiver l'authentification à double facteur",
|
||||
"disable2faDesc": "Saisissez votre mot de passe pour désactiver l'authentification à double facteur"
|
||||
},
|
||||
"general": {
|
||||
"name": "Nom",
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"newPassword": "Nouveau mot de passe",
|
||||
"updatePassword": "Mettre à jour le mot de passe",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "IPs autorisées",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Keepalive persistant",
|
||||
"logout": "Déconnexion",
|
||||
"continue": "Continuer",
|
||||
"host": "Hôte",
|
||||
"port": "Port",
|
||||
"yes": "Oui",
|
||||
"no": "Non",
|
||||
"confirmPassword": "Confirmer le mot de passe",
|
||||
"loading": "Chargement...",
|
||||
"2fa": "Authentification à double facteur",
|
||||
"2faCode": "Code TOTP"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Bienvenue dans votre première installation de wg-easy",
|
||||
"welcomeDesc": "Vous avez trouvé la façon la plus simple d'installer et de gérer WireGuard sur n'importe quel hôte Linux.",
|
||||
"existingSetup": "Avez-vous une installation existante ?",
|
||||
"createAdminDesc": "Veuillez d'abord saisir un nom d'utilisateur administrateur et un mot de passe sécurisé. Ces informations seront utilisées pour vous connecter à votre panel d'administration.",
|
||||
"setupConfigDesc": "Veuillez saisir les informations relatives à l'hôte et au port. Ceci sera utilisé pour la configuration du client lors de la mise en place de WireGuard sur les appareils.",
|
||||
"setupMigrationDesc": "Veuillez fournir le fichier de sauvegarde si vous souhaitez migrer vos données de la version précédente de wg-easy vers votre nouvelle installation.",
|
||||
"upload": "Téléverser",
|
||||
"migration": "Restaurer la sauvegarde:",
|
||||
"createAccount": "Créer un compte",
|
||||
"successful": "Installation réussie",
|
||||
"hostDesc": "Nom d'hôte public auquel les clients se connecteront",
|
||||
"portDesc": "Port UDP public auquel les clients se connecteront et sur lequel WireGuard écoutera"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Une mise à jour est disponible!",
|
||||
"update": "Mise à jour"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Thème sombre",
|
||||
"light": "Thème clair",
|
||||
"system": "Thème système"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Afficher/masquer les graphiques",
|
||||
"donate": "Donation"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Se connecter",
|
||||
"rememberMe": "Se souvenir de moi",
|
||||
"rememberMeDesc": "Rester connecté après avoir fermé le navigateur",
|
||||
"insecure": "Vous ne pouvez pas vous connecter avec une connexion non sécurisée. Utilisez HTTPS.",
|
||||
"2faRequired": "Une authentification à double facteur est requise",
|
||||
"2faWrong": "L'authentification à double facteur est incorrecte"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Il n'y a pas encore de clients.",
|
||||
"newShort": "Nouveau",
|
||||
"sort": "Trier",
|
||||
"create": "Créer un client",
|
||||
"created": "Client créé",
|
||||
"new": "Nouveau client",
|
||||
"name": "Nom",
|
||||
"expireDate": "Date d'expiration",
|
||||
"expireDateDesc": "Date à laquelle le client sera désactivé. Vide pour permanent",
|
||||
"deleteClient": "Supprimer le client",
|
||||
"deleteDialog1": "Êtes-vous sûr de vouloir supprimer",
|
||||
"deleteDialog2": "Cette action ne peut être annulée.",
|
||||
"enabled": "Activé",
|
||||
"address": "Adresse",
|
||||
"serverAllowedIps": "Serveur IPs autorisées",
|
||||
"otlDesc": "Générer un lien court et unique",
|
||||
"permanent": "Permanent",
|
||||
"createdOn": "Créé le ",
|
||||
"lastSeen": "Dernière visite le ",
|
||||
"totalDownload": "Téléchargement total: ",
|
||||
"totalUpload": "Téléversement total: ",
|
||||
"newClient": "Nouveau client",
|
||||
"disableClient": "Désactiver le client",
|
||||
"enableClient": "Activer le client",
|
||||
"noPrivKey": "Ce client n'a pas de clé privée connue. Impossible de créer une configuration.",
|
||||
"showQR": "Afficher le code QR",
|
||||
"downloadConfig": "Télécharger la configuration",
|
||||
"allowedIpsDesc": "Quelles IPs seront acheminées par le VPN (remplace la configuration globale)",
|
||||
"serverAllowedIpsDesc": "Les IPs que le serveur acheminera vers le client",
|
||||
"mtuDesc": "Définit le nombre maximum d'unités de transmission (taille des paquets) pour le tunnel VPN.",
|
||||
"persistentKeepaliveDesc": "Définit l'intervalle (en secondes) pour les paquets keep-alive. 0 le désactive",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Les hooks ne fonctionnent qu'avec wg-quick",
|
||||
"hooksLeaveEmpty": "Uniquement pour wg-quick. Sinon, laissez-le vide",
|
||||
"dnsDesc": "Serveur DNS que les clients utiliseront (remplace la configuration globale)"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Modifier",
|
||||
"cancel": "Annuler",
|
||||
"create": "Créer"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Réussite",
|
||||
"saved": "Sauvegardé",
|
||||
"error": "Erreur"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Actions",
|
||||
"save": "Sauvegarder",
|
||||
"revert": "Revenir en arrière",
|
||||
"sectionGeneral": "Général",
|
||||
"sectionAdvanced": "Avancé",
|
||||
"noItems": "Aucun élément",
|
||||
"nullNoItems": "Aucun élément. Utilisation de la configuration globale",
|
||||
"add": "Ajouter"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Délai d'expiration de la session",
|
||||
"sessionTimeoutDesc": "Durée de la session pour Se souvenir de moi (secondes)",
|
||||
"metrics": "Métriques",
|
||||
"metricsPassword": "Mot de passe",
|
||||
"metricsPasswordDesc": "Mot de passe Bearer pour le endpoint des métriques (mot de passe ou argon2 hash)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Acheminement pour les métriques au format JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Acheminement pour les métriques de Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "Connexion",
|
||||
"hostDesc": "Nom d'hôte public auquel les clients se connecteront (invalide la configuration)",
|
||||
"portDesc": "Port UDP public auquel les clients se connecteront (invalide la configuration, vous souhaiterez probablement modifier le port d'interface également)",
|
||||
"allowedIpsDesc": "IPs autorisées que les clients utiliseront (configuration globale)",
|
||||
"dnsDesc": "Serveur DNS que les clients utiliseront (configuration globale)",
|
||||
"mtuDesc": "MTU que les clients utiliseront (uniquement pour les nouveaux clients)",
|
||||
"persistentKeepaliveDesc": "Intervalle en secondes keepalives du serveur. 0 = désactivé (uniquement pour les nouveaux clients)",
|
||||
"suggest": "Suggérer",
|
||||
"suggestDesc": "Choisissez une adresse IP ou un nom d'hôte pour le champ Hôte."
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR modifié",
|
||||
"device": "Périphérique",
|
||||
"deviceDesc": "Périphérique Ethernet dans lequel le trafic wireguard sera transmis.",
|
||||
"mtuDesc": "MTU que WireGuard utilisera",
|
||||
"portDesc": "Port UDP sur lequel WireGuard écoutera (vous souhaiterez probablement changer le port de configuration aussi)",
|
||||
"changeCidr": "Modifier CIDR",
|
||||
"restart": "Redémarrer l'interface",
|
||||
"restartDesc": "Redémarre l'interface WireGuard",
|
||||
"restartWarn": "Êtes-vous sûr de redémarrer l'interface ? Cela déconnectera tous les clients.",
|
||||
"restartSuccess": "Interface redémarrée"
|
||||
},
|
||||
"introText": "Bienvenue dans le panel d'administration.\n\nVous pouvez y gérer les paramètres généraux, la configuration, les paramètres de l'interface et les hooks.\n\nCommencez par choisir l'une des sections de la barre latérale."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} est requis",
|
||||
"validNumber": "{0} doit être un nombre valide",
|
||||
"validString": "{0} doit être une chaîne de caractères valide",
|
||||
"validBoolean": "{0} doit être une variable valide",
|
||||
"validArray": "{0} doit être un tableau valide",
|
||||
"stringMin": "{0} doit être d'au moins {1} Caractère",
|
||||
"numberMin": "{0} doit être d'au moins {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "Client ID",
|
||||
"name": "Nom",
|
||||
"expiresAt": "Expire le",
|
||||
"address4": "Adresse IPv4",
|
||||
"address6": "Adresse IPv6",
|
||||
"serverAllowedIps": "Serveur IPs autorisées"
|
||||
},
|
||||
"user": {
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"remember": "Se souvenir",
|
||||
"name": "Nom",
|
||||
"email": "Email",
|
||||
"emailInvalid": "L'email doit être valide",
|
||||
"passwordMatch": "Les mots de passe doivent correspondre",
|
||||
"totpEnable": "Activer TOTP",
|
||||
"totpEnableTrue": "Activer TOTP doit être activé",
|
||||
"totpCode": "Code TOTP"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Hôte"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Délai d'expiration de la session",
|
||||
"metricsEnabled": "Métriques",
|
||||
"metricsPassword": "Mot de passe métriques"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Périphérique",
|
||||
"cidrValid": "CIDR doit être valide"
|
||||
},
|
||||
"otl": "Lien unique",
|
||||
"stringMalformed": "La chaîne est malformée",
|
||||
"body": "Le corps doit être un objet valide",
|
||||
"hook": "Hook",
|
||||
"enabled": "Activé",
|
||||
"mtu": "MTU",
|
||||
"port": "Port",
|
||||
"persistentKeepalive": "Keepalive persistant",
|
||||
"address": "Adresse IP",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "IPs autorisées",
|
||||
"file": "Fichier"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "Обліковий запис",
|
||||
"clients": "Клієнти",
|
||||
"admin": {
|
||||
"panel": "Панель адміністратора",
|
||||
"general": "Загальні налаштування",
|
||||
"config": "Конфігурація",
|
||||
"interface": "Інтерфейс",
|
||||
"hooks": "Hooks"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "Електронна пошта"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "Поточний пароль",
|
||||
"enable2fa": "Увімкнути двофакторну автентифікацію",
|
||||
"enable2faDesc": "Відскануйте QR-код за допомогою програми автентифікації або введіть ключ вручну.",
|
||||
"2faKey": "TOTP Ключ",
|
||||
"2faCodeDesc": "Введіть код з вашої програми автентифікатора.",
|
||||
"disable2fa": "Вимкнути двофакторну автентифікацію",
|
||||
"disable2faDesc": "Введіть свій пароль, щоб вимкнути двофакторну автентифікацію."
|
||||
},
|
||||
"general": {
|
||||
"name": "Ім'я",
|
||||
"username": "Ім'я користувача",
|
||||
"password": "Пароль",
|
||||
"newPassword": "Новий пароль",
|
||||
"updatePassword": "Оновити пароль",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "Дозволені IP",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "Постійна підтримка активності",
|
||||
"logout": "Вийти",
|
||||
"continue": "Продовжити",
|
||||
"host": "Хост",
|
||||
"port": "Порт",
|
||||
"yes": "Так",
|
||||
"no": "Ні",
|
||||
"confirmPassword": "Підтвердити пароль",
|
||||
"loading": "Завантаження...",
|
||||
"2fa": "Двофакторна автентифікація",
|
||||
"2faCode": "TOTP код"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Ласкаво просимо до вашого першого налаштування wg-easy",
|
||||
"welcomeDesc": "Ви знайшли найпростіший спосіб встановити та керувати WireGuard на будь-якому хості Linux",
|
||||
"existingSetup": "Ви маєте існуючу конфігурацію?",
|
||||
"createAdminDesc": "Спочатку введіть ім'я адміністратора та надійний пароль. Ці дані використовуватимуться для входу в панель адміністратора.",
|
||||
"setupConfigDesc": "Введіть інформацію про хост і порт. Вона буде використана у конфігурації клієнта при налаштуванні WireGuard на їх пристроях.",
|
||||
"setupMigrationDesc": "Будь ласка, надайте файл резервної копії, якщо ви хочете перенести дані з попередньої версії wg-easy до нової конфігурації.",
|
||||
"upload": "Завантажити",
|
||||
"migration": "Відновити резервну копію:",
|
||||
"createAccount": "Створити обліковий запис",
|
||||
"successful": "Налаштування успішне",
|
||||
"hostDesc": "Публічне ім'я хоста для підключення клієнтів",
|
||||
"portDesc": "Публічний UDP порт, на якому клієнти підключаються і який слухає WireGuard"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "Доступне оновлення!",
|
||||
"update": "Оновлення"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "Темна тема",
|
||||
"light": "Світла тема",
|
||||
"system": "Системна тема"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "Показати/приховати діаграми",
|
||||
"donate": "Пожертвувати"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "Увійти",
|
||||
"rememberMe": "Запам'ятай мене",
|
||||
"rememberMeDesc": "Залишатися в системі після закриття браузера",
|
||||
"insecure": "Ви не можете увійти через незахищене з'єднання. Використовуйте HTTPS.",
|
||||
"2faRequired": "Потрібна двофакторна автентифікація",
|
||||
"2faWrong": "Неправильний код двофакторної автентифікації"
|
||||
},
|
||||
"client": {
|
||||
"empty": "Клієнтів поки немає.",
|
||||
"newShort": "Новий",
|
||||
"sort": "Сортувати",
|
||||
"create": "Створити клієнта",
|
||||
"created": "Клієнт створено",
|
||||
"new": "Новий клієнт",
|
||||
"name": "Ім'я",
|
||||
"expireDate": "Термін дії",
|
||||
"expireDateDesc": "Дата, коли клієнт буде відключений. Порожнє для постійного користування",
|
||||
"deleteClient": "Видалити клієнта",
|
||||
"deleteDialog1": "Ви впевнені, що бажаєте видалити",
|
||||
"deleteDialog2": "Цю дію неможливо скасувати.",
|
||||
"enabled": "Увімкнено",
|
||||
"address": "Адреса",
|
||||
"serverAllowedIps": "Дозволені IP-адреси сервера",
|
||||
"otlDesc": "Створити коротке одноразове посилання",
|
||||
"permanent": "Постійний",
|
||||
"createdOn": "Створено ",
|
||||
"lastSeen": "Останнє підключення в ",
|
||||
"totalDownload": "Всього завантажено: ",
|
||||
"totalUpload": "Всього відправлено: ",
|
||||
"newClient": "Новий клієнт",
|
||||
"disableClient": "Вимкнути клієнта",
|
||||
"enableClient": "Увімкнути клієнта",
|
||||
"noPrivKey": "У цього клієнта відсутній приватний ключ. Неможливо створити конфігурацію.",
|
||||
"showQR": "Показати QR-код",
|
||||
"downloadConfig": "Завантажити конфігурацію",
|
||||
"allowedIpsDesc": "Які IP-адреси будуть маршрутизовані через VPN (перевизначає глобальну конфігурацію)",
|
||||
"serverAllowedIpsDesc": "Які IP-адреси сервер буде перенаправляти до клієнта",
|
||||
"mtuDesc": "Встановлює максимальний розмір пакета (одиницю передачі) для VPN-тунелю",
|
||||
"persistentKeepaliveDesc": "Встановлює інтервал (у секундах) для пакетів keep-alive. 0 вимикає його",
|
||||
"hooks": "Hooks",
|
||||
"hooksDescription": "Hooks працюють лише з wg-quick",
|
||||
"hooksLeaveEmpty": "Тільки для wg-quick. Інакше залиште порожнім",
|
||||
"dnsDesc": "DNS сервер, який використовуватимуть клієнти (перевизначає глобальну конфігурацію)"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "Змінити",
|
||||
"cancel": "Скасувати",
|
||||
"create": "Створити"
|
||||
},
|
||||
"toast": {
|
||||
"success": "Успіх",
|
||||
"saved": "Збережено",
|
||||
"error": "Помилка"
|
||||
},
|
||||
"form": {
|
||||
"actions": "Дії",
|
||||
"save": "Зберегти",
|
||||
"revert": "Повернути",
|
||||
"sectionGeneral": "Загальні",
|
||||
"sectionAdvanced": "Додатково",
|
||||
"noItems": "Немає елементів",
|
||||
"nullNoItems": "Немає елементів. Використовується глобальна конфігурація",
|
||||
"add": "Додати"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "Час очікування сеансу",
|
||||
"sessionTimeoutDesc": "Тривалість сеансу для функції 'Запам'ятати мене' (секунди)",
|
||||
"metrics": "Метрики",
|
||||
"metricsPassword": "Пароль",
|
||||
"metricsPasswordDesc": "Пароль Bearer для точки доступу метрик (пароль або хеш argon2)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "Маршрут для метрик у форматі JSON",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Маршрут для метрики Prometheus"
|
||||
},
|
||||
"config": {
|
||||
"connection": "З'єднання",
|
||||
"hostDesc": "Публічне ім'я хоста для підключення клієнтів (спрацьовує при зміні конфігурації)",
|
||||
"portDesc": "Публічний UDP порт для підключення клієнтів (спрацьовує при зміні конфігурації, можливо, варто змінити порт інтерфейсу теж)",
|
||||
"allowedIpsDesc": "Дозволені IP-адреси, які використовуватимуть клієнти (глобальна конфігурація)",
|
||||
"dnsDesc": "DNS-сервера, який використовуватимуть клієнти (глобальну конфігурацію)",
|
||||
"mtuDesc": "MTU, який використовуватимуть клієнти (лише для нових клієнтів)",
|
||||
"persistentKeepaliveDesc": "Інтервал у секундах для надсилання keepalive на сервер. 0 = вимкнено (лише для нових клієнтів)",
|
||||
"suggest": "Запропонувати",
|
||||
"suggestDesc": "Виберіть IP-адресу або ім'я хоста для поля 'Хост'"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR змінено",
|
||||
"device": "Пристрій",
|
||||
"deviceDesc": "Ethernet-пристрій, через який має проходити трафік WireGuard",
|
||||
"mtuDesc": "MTU, яке використовуватиме WireGuard",
|
||||
"portDesc": "UDP порт, який слухатиме WireGuard (ймовірно, варто змінити порт у конфігурації теж)",
|
||||
"changeCidr": "Змінити CIDR",
|
||||
"restart": "Перезавантажити інтерфейс",
|
||||
"restartDesc": "Перезавантажити інтерфейс WireGuard",
|
||||
"restartWarn": "Ви впевнені, що бажаєте перезавантажити інтерфейс? Це призведе до відключення всіх клієнтів.",
|
||||
"restartSuccess": "Інтерфейс перезавантажено"
|
||||
},
|
||||
"introText": "Ласкаво просимо до панелі адміністратора.\n\nТут ви можете керувати загальними налаштуваннями, конфігурацією, налаштуваннями інтерфейсу та перехоплювачами.\n\nПочніть з вибору одного з розділів на боковій панелі."
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0} обов'язковий",
|
||||
"validNumber": "{0} має бути дійсним числом",
|
||||
"validString": "{0} має бути дійсним рядком",
|
||||
"validBoolean": "{0} має бути дійсним логічним значенням",
|
||||
"validArray": "{0} має бути дійсним масивом",
|
||||
"stringMin": "{0} має містити щонайменше {1} символів",
|
||||
"numberMin": "{0} має бути щонайменше {1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "Ідентифікатор клієнта",
|
||||
"name": "Ім'я",
|
||||
"expiresAt": "Термін дії закінчується о",
|
||||
"address4": "IPv4-адреса",
|
||||
"address6": "IPv6-адреса",
|
||||
"serverAllowedIps": "Дозволені IP-адреси сервера"
|
||||
},
|
||||
"user": {
|
||||
"username": "Ім'я користувача",
|
||||
"password": "Пароль",
|
||||
"remember": "Пам'ятати",
|
||||
"name": "Ім'я",
|
||||
"email": "Електронна пошта",
|
||||
"emailInvalid": "Email має бути дійсною",
|
||||
"passwordMatch": "Паролі мають збігатися",
|
||||
"totpEnable": "Увімкнути TOTP",
|
||||
"totpEnableTrue": "Увімкнення TOTP має бути true",
|
||||
"totpCode": "TOTP Код"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "Хост"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "Час очікування сеансу",
|
||||
"metricsEnabled": "Метрики",
|
||||
"metricsPassword": "Пароль метрик"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "Пристрій",
|
||||
"cidrValid": "CIDR має бути дійсним"
|
||||
},
|
||||
"otl": "Одноразове посилання",
|
||||
"stringMalformed": "Рядок має неправильний формат",
|
||||
"body": "Тіло має бути коректним об'єктом",
|
||||
"hook": "Hook",
|
||||
"enabled": "Увімкнено",
|
||||
"mtu": "MTU",
|
||||
"port": "Порт",
|
||||
"persistentKeepalive": "Постійна підтримка активності",
|
||||
"address": "IP-адреса",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "Дозволені IP-адреси",
|
||||
"file": "Файл"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "账户管理",
|
||||
"clients": "客户端管理",
|
||||
"admin": {
|
||||
"panel": "管理面板",
|
||||
"general": "通用设置",
|
||||
"config": "网络配置",
|
||||
"interface": "接口配置",
|
||||
"hooks": "钩子脚本"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "电子邮箱"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "当前密码",
|
||||
"enable2fa": "启用双重认证",
|
||||
"enable2faDesc": "使用认证器应用扫描二维码或手动输入密钥进行配置",
|
||||
"2faKey": "TOTP密钥",
|
||||
"2faCodeDesc": "请输入您的认证器应用生成的验证码",
|
||||
"disable2fa": "禁用双重认证",
|
||||
"disable2faDesc": "您需要输入当前密码来禁用双重认证功能"
|
||||
},
|
||||
"general": {
|
||||
"name": "名称",
|
||||
"username": "用户名",
|
||||
"password": "密码",
|
||||
"newPassword": "新密码",
|
||||
"updatePassword": "更新密码",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "允许的IP",
|
||||
"dns": "DNS",
|
||||
"persistentKeepalive": "保活间隔",
|
||||
"logout": "注销登录",
|
||||
"continue": "继续",
|
||||
"host": "主机",
|
||||
"port": "端口",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"confirmPassword": "确认密码",
|
||||
"loading": "加载中...",
|
||||
"2fa": "双重认证",
|
||||
"2faCode": "验证码"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "欢迎使用wg-easy安装向导",
|
||||
"welcomeDesc": "您正在使用最简单的WireGuard Linux主机安装和管理方案",
|
||||
"existingSetup": "是否已有现有配置?",
|
||||
"createAdminDesc": "请首先输入管理员用户名和强密码。这些信息将用于登录管理面板。",
|
||||
"setupConfigDesc": "请输入服务器主机和端口信息。这些设置将用于客户端设备连接WireGuard时的配置。",
|
||||
"setupMigrationDesc": "如果您希望从旧版wg-easy迁移数据到新安装,请提供备份文件。",
|
||||
"upload": "上传文件",
|
||||
"migration": "从备份恢复配置:",
|
||||
"createAccount": "创建账户",
|
||||
"successful": "安装配置成功",
|
||||
"hostDesc": "客户端将连接到的公共主机名或IP地址",
|
||||
"portDesc": "客户端将连接到的公共UDP端口,也是WireGuard服务监听的端口"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "检测到可用更新!",
|
||||
"update": "立即更新"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "深色模式",
|
||||
"light": "浅色模式",
|
||||
"system": "系统默认"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "显示/隐藏 流量图表",
|
||||
"donate": "捐赠支持"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "登录系统",
|
||||
"rememberMe": "记住我",
|
||||
"rememberMeDesc": "关闭浏览器后保持登录状态",
|
||||
"insecure": "无法通过不安全连接登录。请使用HTTPS。",
|
||||
"2faRequired": "需要进行双重认证",
|
||||
"2faWrong": "双重认证验证码错误"
|
||||
},
|
||||
"client": {
|
||||
"empty": "当前没有客户端配置",
|
||||
"newShort": "新建",
|
||||
"sort": "排序",
|
||||
"create": "创建客户端",
|
||||
"created": "客户端创建成功",
|
||||
"new": "新建客户端",
|
||||
"name": "客户端名称",
|
||||
"expireDate": "过期日期",
|
||||
"expireDateDesc": "客户端将被自动禁用的日期。留空表示永久有效",
|
||||
"deleteClient": "删除客户端",
|
||||
"deleteDialog1": "您确定要删除此客户端吗?",
|
||||
"deleteDialog2": "此操作无法撤销。",
|
||||
"enabled": "已启用",
|
||||
"address": "IP地址",
|
||||
"serverAllowedIps": "服务端允许的IP",
|
||||
"otlDesc": "生成一次性使用的短链接配置",
|
||||
"permanent": "永久有效",
|
||||
"createdOn": "创建于 ",
|
||||
"lastSeen": "最后在线时间 ",
|
||||
"totalDownload": "总下载流量: ",
|
||||
"totalUpload": "总上传流量: ",
|
||||
"newClient": "新建客户端",
|
||||
"disableClient": "禁用客户端",
|
||||
"enableClient": "启用客户端",
|
||||
"noPrivKey": "此客户端没有已知的私钥,无法创建配置文件",
|
||||
"showQR": "显示二维码",
|
||||
"downloadConfig": "下载配置文件",
|
||||
"allowedIpsDesc": "指定将通过VPN路由的IP地址(覆盖全局配置)",
|
||||
"serverAllowedIpsDesc": "指定服务端将路由到客户端的IP地址范围",
|
||||
"mtuDesc": "设置VPN隧道的MTU(最大传输单元)",
|
||||
"persistentKeepaliveDesc": "设置保活数据包的发送间隔(秒)。0表示禁用",
|
||||
"hooks": "钩子脚本",
|
||||
"hooksDescription": "钩子脚本仅在使用wg-quick时有效",
|
||||
"hooksLeaveEmpty": "如果不使用wg-quick,请留空此字段"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "确认修改",
|
||||
"cancel": "取消",
|
||||
"create": "创建"
|
||||
},
|
||||
"toast": {
|
||||
"success": "操作成功",
|
||||
"saved": "保存成功",
|
||||
"error": "发生错误"
|
||||
},
|
||||
"form": {
|
||||
"actions": "操作",
|
||||
"save": "保存更改",
|
||||
"revert": "恢复默认",
|
||||
"sectionGeneral": "基本配置",
|
||||
"sectionAdvanced": "高级选项",
|
||||
"noItems": "未配置",
|
||||
"nullNoItems": "未配置。将使用全局配置",
|
||||
"add": "添加"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "会话超时时间",
|
||||
"sessionTimeoutDesc": "'记住我'功能的会话持续时间(秒)",
|
||||
"metrics": "监控指标",
|
||||
"metricsPassword": "密码",
|
||||
"metricsPasswordDesc": "用于监控端点的Bearer密码(支持密码或Argon2哈希)",
|
||||
"json": "JSON格式",
|
||||
"jsonDesc": "获取JSON格式的监控数据路由",
|
||||
"prometheus": "Prometheus格式",
|
||||
"prometheusDesc": "获取Prometheus格式监控数据的路由"
|
||||
},
|
||||
"config": {
|
||||
"connection": "连接设置",
|
||||
"hostDesc": "客户端将连接到的公共主机名(修改会使现有配置失效)",
|
||||
"portDesc": "客户端将连接到的公共UDP端口(修改会使现有配置失效,通常需要同时修改接口端口)",
|
||||
"allowedIpsDesc": "客户端使用的全局允许的IP范围",
|
||||
"dnsDesc": "客户端使用的全局DNS设置",
|
||||
"mtuDesc": "新客户端将使用的MTU(仅影响新客户端)",
|
||||
"persistentKeepaliveDesc": "向服务器发送保活数据包的间隔秒数。0表示禁用(仅影响新客户端)",
|
||||
"suggest": "自动检测",
|
||||
"suggestDesc": "为'主机'字段选择IP地址或主机名"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "CIDR修改成功",
|
||||
"device": "网络设备",
|
||||
"deviceDesc": "用于转发WireGuard流量的以太网设备",
|
||||
"mtuDesc": "WireGuard接口使用的MTU",
|
||||
"portDesc": "WireGuard监听的UDP端口(通常需要同时修改配置端口)",
|
||||
"changeCidr": "修改CIDR",
|
||||
"restart": "重启接口",
|
||||
"restartDesc": "重新启动WireGuard接口",
|
||||
"restartWarn": "确定要重启接口吗?这将断开所有客户端的连接。",
|
||||
"restartSuccess": "接口重启成功"
|
||||
},
|
||||
"introText": "欢迎使用管理控制台。\n\n您可以在这里管理通用设置、网络配置、接口设置和钩子脚本。\n\n请从侧边栏选择一个功能模块开始。"
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0}是必填项",
|
||||
"validNumber": "{0}必须是有效数字",
|
||||
"validString": "{0}必须是有效文本",
|
||||
"validBoolean": "{0}必须是是/否选项",
|
||||
"validArray": "{0}必须是有效数组",
|
||||
"stringMin": "{0}至少需要{1}个字符",
|
||||
"numberMin": "{0}不能小于{1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "客户端ID",
|
||||
"name": "客户端名称",
|
||||
"expiresAt": "过期时间",
|
||||
"address4": "IPv4地址",
|
||||
"address6": "IPv6地址",
|
||||
"serverAllowedIps": "服务端允许的IP"
|
||||
},
|
||||
"user": {
|
||||
"username": "用户名",
|
||||
"password": "密码",
|
||||
"remember": "记住登录",
|
||||
"name": "姓名",
|
||||
"email": "电子邮箱",
|
||||
"emailInvalid": "请输入有效的电子邮箱地址",
|
||||
"passwordMatch": "两次输入的密码必须一致",
|
||||
"totpEnable": "启用TOTP",
|
||||
"totpEnableTrue": "必须启用双重认证",
|
||||
"totpCode": "验证码"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "服务器地址"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "会话超时",
|
||||
"metricsEnabled": "启用监控",
|
||||
"metricsPassword": "监控密码"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "网络设备",
|
||||
"cidrValid": "CIDR必须有效"
|
||||
},
|
||||
"otl": "一次性链接",
|
||||
"stringMalformed": "文本格式错误",
|
||||
"body": "请求体必须是有效对象",
|
||||
"hook": "钩子脚本",
|
||||
"enabled": "启用状态",
|
||||
"mtu": "MTU",
|
||||
"port": "端口",
|
||||
"persistentKeepalive": "保活间隔",
|
||||
"address": "IP地址",
|
||||
"dns": "DNS",
|
||||
"allowedIps": "允许的IP",
|
||||
"file": "文件"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "启动前脚本",
|
||||
"postUp": "启动后脚本",
|
||||
"preDown": "停止前脚本",
|
||||
"postDown": "停止后脚本"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"pages": {
|
||||
"me": "帳戶",
|
||||
"clients": "客戶端",
|
||||
"admin": {
|
||||
"panel": "管理員版面",
|
||||
"general": "一般設定",
|
||||
"config": "配置設定",
|
||||
"interface": "介面設定",
|
||||
"hooks": "掛鉤設定"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"email": "電郵"
|
||||
},
|
||||
"me": {
|
||||
"currentPassword": "目前密碼",
|
||||
"enable2fa": "啟用雙重認證",
|
||||
"enable2faDesc": "使用認證應用程式掃描二維碼,或手動輸入密匙。",
|
||||
"2faKey": "TOTP密匙",
|
||||
"2faCodeDesc": "請輸入認證應用程式中的驗證碼。",
|
||||
"disable2fa": "停用雙重認證",
|
||||
"disable2faDesc": "請輸入密碼以停用雙重認證。"
|
||||
},
|
||||
"general": {
|
||||
"name": "名稱",
|
||||
"username": "用戶名",
|
||||
"password": "密碼",
|
||||
"newPassword": "新密碼",
|
||||
"updatePassword": "更改密碼",
|
||||
"mtu": "MTU",
|
||||
"allowedIps": "IP白名單",
|
||||
"dns": "域名系統",
|
||||
"persistentKeepalive": "保持連線",
|
||||
"logout": "登出",
|
||||
"continue": "繼續",
|
||||
"host": "主機",
|
||||
"port": "連接埠",
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
"confirmPassword": "確認新密碼",
|
||||
"loading": "載入中...",
|
||||
"2fa": "雙重認證",
|
||||
"2faCode": "TOTP驗證碼"
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "歡迎首次設定wg-easy",
|
||||
"welcomeDesc": "這是最簡單的方法讓你在任何Linux主機上安裝及管理WireGuard",
|
||||
"existingSetup": "你有現存設定嗎?",
|
||||
"createAdminDesc": "請輸入管理員用戶名及一個高強度密碼。這些資料將用於登入管理員版面。",
|
||||
"setupConfigDesc": "請輸入主機及連接埠資料。這將用於客戶端設定,以便在他們的裝置上設定WireGuard。",
|
||||
"setupMigrationDesc": "如果你想將舊版wg-easy的資料轉移到新設定,請提供備份檔案。",
|
||||
"upload": "上傳",
|
||||
"migration": "還原備份:",
|
||||
"createAccount": "建立帳戶",
|
||||
"successful": "設定成功",
|
||||
"hostDesc": "客戶端連接的公共主機名稱",
|
||||
"portDesc": "客戶端和WireGuard使用的公共UDP連接埠"
|
||||
},
|
||||
"update": {
|
||||
"updateAvailable": "有新版本更新!",
|
||||
"update": "更新"
|
||||
},
|
||||
"theme": {
|
||||
"dark": "深色模式",
|
||||
"light": "淺色模式",
|
||||
"system": "系統預設"
|
||||
},
|
||||
"layout": {
|
||||
"toggleCharts": "顯示或隱藏圖表",
|
||||
"donate": "贊助"
|
||||
},
|
||||
"login": {
|
||||
"signIn": "登入",
|
||||
"rememberMe": "保持登入",
|
||||
"rememberMeDesc": "關閉瀏覽器後仍保持登入",
|
||||
"insecure": "連線不安全,請使用HTTPS。",
|
||||
"2faRequired": "需要雙重認證",
|
||||
"2faWrong": "雙重認證失敗"
|
||||
},
|
||||
"client": {
|
||||
"empty": "目前沒有客戶端。",
|
||||
"newShort": "新增",
|
||||
"sort": "排序",
|
||||
"create": "建立客戶端",
|
||||
"created": "客戶端已建立",
|
||||
"new": "新增客戶端",
|
||||
"name": "名稱",
|
||||
"expireDate": "有效期",
|
||||
"expireDateDesc": "客戶端將於此日期停用。留空則為永久有效",
|
||||
"deleteClient": "刪除客戶端",
|
||||
"deleteDialog1": "你確定要刪除",
|
||||
"deleteDialog2": "此操作無法還原。",
|
||||
"enabled": "已啟用",
|
||||
"address": "IP地址",
|
||||
"serverAllowedIps": "伺服器IP白名單",
|
||||
"otlDesc": "生成短暫單次超連結",
|
||||
"permanent": "永久",
|
||||
"createdOn": "建立於",
|
||||
"lastSeen": "上次活動於",
|
||||
"totalDownload": "總下載量:",
|
||||
"totalUpload": "總上傳量:",
|
||||
"newClient": "新客戶端",
|
||||
"disableClient": "停用客戶端",
|
||||
"enableClient": "啟用客戶端",
|
||||
"noPrivKey": "此客戶端沒有已知的密匙。無法建立配置。",
|
||||
"showQR": "顯示二維碼",
|
||||
"downloadConfig": "下載配置",
|
||||
"allowedIpsDesc": "通過VPN的IP地址(取代全局配置)",
|
||||
"serverAllowedIpsDesc": "伺服器路由到客戶端的IP地址",
|
||||
"mtuDesc": "設定VPN隧道的最大傳輸單位(封包大小)",
|
||||
"persistentKeepaliveDesc": "設定保持連線封包的秒數間隔。0代表停用",
|
||||
"hooks": "掛鉤",
|
||||
"hooksDescription": "掛鉤僅適用於wg-quick",
|
||||
"hooksLeaveEmpty": "僅適用於wg-quick,否則請留空",
|
||||
"dnsDesc": "客戶端使用的域名系統伺服器(取代全局配置)"
|
||||
},
|
||||
"dialog": {
|
||||
"change": "更改",
|
||||
"cancel": "取消",
|
||||
"create": "創建"
|
||||
},
|
||||
"toast": {
|
||||
"success": "成功",
|
||||
"saved": "已保存",
|
||||
"error": "錯誤"
|
||||
},
|
||||
"form": {
|
||||
"actions": "操作",
|
||||
"save": "保存",
|
||||
"revert": "重置",
|
||||
"sectionGeneral": "一般設定",
|
||||
"sectionAdvanced": "進階",
|
||||
"noItems": "未有設定",
|
||||
"nullNoItems": "未有設定,使用全局配置",
|
||||
"add": "新增"
|
||||
},
|
||||
"admin": {
|
||||
"general": {
|
||||
"sessionTimeout": "工作階段逾時",
|
||||
"sessionTimeoutDesc": "「保持登入」的工作階段持續時間(秒)",
|
||||
"metrics": "指標",
|
||||
"metricsPassword": "密碼",
|
||||
"metricsPasswordDesc": "指標端點的Bearer密碼(密碼或argon2雜湊)",
|
||||
"json": "JSON",
|
||||
"jsonDesc": "JSON格式指標的路由",
|
||||
"prometheus": "Prometheus",
|
||||
"prometheusDesc": "Prometheus指標的路由"
|
||||
},
|
||||
"config": {
|
||||
"connection": "連線",
|
||||
"hostDesc": "客戶端連接的公共主機名稱(使配置無效)",
|
||||
"portDesc": "客戶端連接的公共UDP連接埠(使配置無效,你可能也想更改介面連接埠)",
|
||||
"allowedIpsDesc": "客戶端使用的IP白名單(全局配置)",
|
||||
"dnsDesc": "客戶端使用的域名系統伺服器(全局配置)",
|
||||
"mtuDesc": "客戶端使用的MTU(僅適用於新客戶端)",
|
||||
"persistentKeepaliveDesc": "向伺服器發送保持連線封包的秒數間隔。0代表停用(僅適用於新客戶端)",
|
||||
"suggest": "建議",
|
||||
"suggestDesc": "選擇一個IP地址或主機名稱"
|
||||
},
|
||||
"interface": {
|
||||
"cidrSuccess": "成功更改CIDR",
|
||||
"device": "裝置",
|
||||
"deviceDesc": "WireGuard流量通過的乙太網路裝置",
|
||||
"mtuDesc": "WireGuard使用的MTU",
|
||||
"portDesc": "WireGuard監聽的UDP連接埠 (你可能也想更改設定連接埠)",
|
||||
"changeCidr": "更改CIDR",
|
||||
"restart": "重啟介面",
|
||||
"restartDesc": "重啟WireGuard介面",
|
||||
"restartWarn": "你確定要重新啟動介面嗎?這將中斷所有客戶端連線。",
|
||||
"restartSuccess": "介面已重啟"
|
||||
},
|
||||
"introText": "歡迎來到管理員版面。\n\n你可以在側邊欄中管理一般、配置、介面和掛鉤設定。"
|
||||
},
|
||||
"zod": {
|
||||
"generic": {
|
||||
"required": "{0}為必填項",
|
||||
"validNumber": "{0}必須是有效的數字",
|
||||
"validString": "{0}必須是有效的字串",
|
||||
"validBoolean": "{0}必須是有效的布林值",
|
||||
"validArray": "{0}必須是有效的陣列",
|
||||
"stringMin": "{0}至少需要{1}個字元",
|
||||
"numberMin": "{0}至少為{1}"
|
||||
},
|
||||
"client": {
|
||||
"id": "客戶端ID",
|
||||
"name": "名稱",
|
||||
"expiresAt": "到期於",
|
||||
"address4": "IPv4地址",
|
||||
"address6": "IPv6地址",
|
||||
"serverAllowedIps": "伺服器IP白名單"
|
||||
},
|
||||
"user": {
|
||||
"username": "用戶名",
|
||||
"password": "密碼",
|
||||
"remember": "保持",
|
||||
"name": "名稱",
|
||||
"email": "電郵",
|
||||
"emailInvalid": "必須是有效的電郵地址",
|
||||
"passwordMatch": "密碼必須一致",
|
||||
"totpEnable": "TOTP啟用",
|
||||
"totpEnableTrue": "TOTP啟用必須為正確",
|
||||
"totpCode": "TOTP驗證碼"
|
||||
},
|
||||
"userConfig": {
|
||||
"host": "主機"
|
||||
},
|
||||
"general": {
|
||||
"sessionTimeout": "工作階段逾時",
|
||||
"metricsEnabled": "指標",
|
||||
"metricsPassword": "指標密碼"
|
||||
},
|
||||
"interface": {
|
||||
"cidr": "CIDR",
|
||||
"device": "裝置",
|
||||
"cidrValid": "CIDR必須有效"
|
||||
},
|
||||
"otl": "單次超連結",
|
||||
"stringMalformed": "字串格式不正確",
|
||||
"body": "主體必須是有效的物件",
|
||||
"hook": "掛鉤",
|
||||
"enabled": "已啟動",
|
||||
"mtu": "MTU",
|
||||
"port": "連接埠",
|
||||
"persistentKeepalive": "保持連線",
|
||||
"address": "IP地址",
|
||||
"dns": "域名系統",
|
||||
"allowedIps": "IP白名單",
|
||||
"file": "文件"
|
||||
},
|
||||
"hooks": {
|
||||
"preUp": "PreUp",
|
||||
"postUp": "PostUp",
|
||||
"preDown": "PreDown",
|
||||
"postDown": "PostDown"
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,31 @@ export default defineNuxtConfig({
|
||||
language: 'en-US',
|
||||
name: 'English',
|
||||
},
|
||||
{
|
||||
code: 'uk',
|
||||
language: 'uk-UA',
|
||||
name: 'Українська',
|
||||
},
|
||||
{
|
||||
code: 'fr',
|
||||
language: 'fr-FR',
|
||||
name: 'Français',
|
||||
},
|
||||
{
|
||||
code: 'de',
|
||||
language: 'de-DE',
|
||||
name: 'Deutsch',
|
||||
},
|
||||
{
|
||||
code: 'zh-HK',
|
||||
language: 'zh-HK',
|
||||
name: '繁體中文(香港)',
|
||||
},
|
||||
{
|
||||
code: 'zh-CN',
|
||||
language: 'zh-CN',
|
||||
name: '简体中文',
|
||||
},
|
||||
],
|
||||
defaultLocale: 'en',
|
||||
vueI18n: './i18n.config.ts',
|
||||
|
||||
+15
-20
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wg-easy",
|
||||
"version": "15.0.0",
|
||||
"version": "15.1.0",
|
||||
"description": "The easiest way to run WireGuard VPN + Web-based Admin UI.",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
@@ -22,11 +22,11 @@
|
||||
"dependencies": {
|
||||
"@eschricht/nuxt-color-mode": "^1.1.5",
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@libsql/client": "^0.15.7",
|
||||
"@nuxtjs/i18n": "^9.5.4",
|
||||
"@libsql/client": "^0.15.9",
|
||||
"@nuxtjs/i18n": "^9.5.6",
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"@phc/format": "^1.0.0",
|
||||
"@pinia/nuxt": "^0.11.0",
|
||||
"@pinia/nuxt": "^0.11.1",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"apexcharts": "^4.7.0",
|
||||
"argon2": "^0.43.0",
|
||||
@@ -35,42 +35,37 @@
|
||||
"consola": "^3.4.2",
|
||||
"crc-32": "^1.2.2",
|
||||
"debug": "^4.4.1",
|
||||
"drizzle-orm": "^0.43.1",
|
||||
"drizzle-orm": "^0.44.2",
|
||||
"ip-bigint": "^8.2.1",
|
||||
"is-cidr": "^5.1.1",
|
||||
"is-ip": "^5.0.1",
|
||||
"js-sha256": "^0.11.1",
|
||||
"nuxt": "^3.17.4",
|
||||
"nuxt": "^3.17.5",
|
||||
"otpauth": "^9.4.0",
|
||||
"pinia": "^3.0.2",
|
||||
"qr": "^0.4.2",
|
||||
"pinia": "^3.0.3",
|
||||
"qr": "^0.5.0",
|
||||
"radix-vue": "^1.9.17",
|
||||
"semver": "^7.7.2",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"timeago.js": "^4.0.2",
|
||||
"vue": "latest",
|
||||
"vue3-apexcharts": "^1.8.0",
|
||||
"zod": "^3.25.30"
|
||||
"zod": "^3.25.67"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint": "^1.4.1",
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/phc__format": "^1.0.1",
|
||||
"@types/semver": "^7.7.0",
|
||||
"drizzle-kit": "^0.31.1",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"esbuild": "^0.25.5",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint": "^9.30.0",
|
||||
"eslint-config-prettier": "^10.1.5",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"tsx": "^4.19.4",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.13",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5.8.3",
|
||||
"vue-tsc": "^2.2.10"
|
||||
},
|
||||
"packageManager": "pnpm@10.11.0",
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"oxc-parser": "^0.70.0"
|
||||
}
|
||||
}
|
||||
"packageManager": "pnpm@10.12.4"
|
||||
}
|
||||
|
||||
Generated
+1612
-1651
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ import { drizzle } from 'drizzle-orm/libsql';
|
||||
import { migrate as drizzleMigrate } from 'drizzle-orm/libsql/migrator';
|
||||
import { createClient } from '@libsql/client';
|
||||
import debug from 'debug';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
import * as schema from './schema';
|
||||
import { ClientService } from './repositories/client/service';
|
||||
@@ -25,6 +26,11 @@ export async function connect() {
|
||||
await initialSetup(dbService);
|
||||
}
|
||||
|
||||
if (WG_ENV.DISABLE_IPV6) {
|
||||
DB_DEBUG('Warning: Disabling IPv6...');
|
||||
await disableIpv6(db);
|
||||
}
|
||||
|
||||
return dbService;
|
||||
}
|
||||
|
||||
@@ -108,3 +114,48 @@ async function initialSetup(db: DBServiceType) {
|
||||
await db.general.setSetupStep(0);
|
||||
}
|
||||
}
|
||||
|
||||
async function disableIpv6(db: DBType) {
|
||||
// This should match the initial value migration
|
||||
const postUpMatch =
|
||||
' ip6tables -t nat -A POSTROUTING -s {{ipv6Cidr}} -o {{device}} -j MASQUERADE; ip6tables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT;';
|
||||
const postDownMatch =
|
||||
' ip6tables -t nat -D POSTROUTING -s {{ipv6Cidr}} -o {{device}} -j MASQUERADE; ip6tables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT;';
|
||||
|
||||
await db.transaction(async (tx) => {
|
||||
const hooks = await tx.query.hooks.findFirst({
|
||||
where: eq(schema.hooks.id, 'wg0'),
|
||||
});
|
||||
|
||||
if (!hooks) {
|
||||
throw new Error('Hooks not found');
|
||||
}
|
||||
|
||||
if (hooks.postUp.includes(postUpMatch)) {
|
||||
DB_DEBUG('Disabling IPv6 in Post Up hooks...');
|
||||
await tx
|
||||
.update(schema.hooks)
|
||||
.set({
|
||||
postUp: hooks.postUp.replace(postUpMatch, ''),
|
||||
postDown: hooks.postDown.replace(postDownMatch, ''),
|
||||
})
|
||||
.where(eq(schema.hooks.id, 'wg0'))
|
||||
.execute();
|
||||
} else {
|
||||
DB_DEBUG('IPv6 Post Up hooks already disabled, skipping...');
|
||||
}
|
||||
if (hooks.postDown.includes(postDownMatch)) {
|
||||
DB_DEBUG('Disabling IPv6 in Post Down hooks...');
|
||||
await tx
|
||||
.update(schema.hooks)
|
||||
.set({
|
||||
postUp: hooks.postUp.replace(postUpMatch, ''),
|
||||
postDown: hooks.postDown.replace(postDownMatch, ''),
|
||||
})
|
||||
.where(eq(schema.hooks.id, 'wg0'))
|
||||
.execute();
|
||||
} else {
|
||||
DB_DEBUG('IPv6 Post Down hooks already disabled, skipping...');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,13 +25,21 @@ class WireGuard {
|
||||
const hooks = await Database.hooks.get();
|
||||
|
||||
const result = [];
|
||||
result.push(wg.generateServerInterface(wgInterface, hooks));
|
||||
result.push(
|
||||
wg.generateServerInterface(wgInterface, hooks, {
|
||||
enableIpv6: !WG_ENV.DISABLE_IPV6,
|
||||
})
|
||||
);
|
||||
|
||||
for (const client of clients) {
|
||||
if (!client.enabled) {
|
||||
continue;
|
||||
}
|
||||
result.push(wg.generateServerPeer(client));
|
||||
result.push(
|
||||
wg.generateServerPeer(client, {
|
||||
enableIpv6: !WG_ENV.DISABLE_IPV6,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
result.push('');
|
||||
@@ -125,7 +133,9 @@ class WireGuard {
|
||||
throw new Error('Client not found');
|
||||
}
|
||||
|
||||
return wg.generateClientConfig(wgInterface, userConfig, client);
|
||||
return wg.generateClientConfig(wgInterface, userConfig, client, {
|
||||
enableIpv6: !WG_ENV.DISABLE_IPV6,
|
||||
});
|
||||
}
|
||||
|
||||
async getClientQRCodeSVG({ clientId }: { clientId: ID }) {
|
||||
|
||||
@@ -17,6 +17,8 @@ export const WG_ENV = {
|
||||
INSECURE: process.env.INSECURE === 'true',
|
||||
/** Port the UI is listening on */
|
||||
PORT: assertEnv('PORT'),
|
||||
/** If IPv6 should be disabled */
|
||||
DISABLE_IPV6: process.env.DISABLE_IPV6 === 'true',
|
||||
};
|
||||
|
||||
export const WG_INITIAL_ENV = {
|
||||
|
||||
@@ -5,11 +5,20 @@ import type { InterfaceType } from '#db/repositories/interface/types';
|
||||
import type { UserConfigType } from '#db/repositories/userConfig/types';
|
||||
import type { HooksType } from '#db/repositories/hooks/types';
|
||||
|
||||
type Options = {
|
||||
enableIpv6?: boolean;
|
||||
};
|
||||
|
||||
export const wg = {
|
||||
generateServerPeer: (client: Omit<ClientType, 'createdAt' | 'updatedAt'>) => {
|
||||
generateServerPeer: (
|
||||
client: Omit<ClientType, 'createdAt' | 'updatedAt'>,
|
||||
options: Options = {}
|
||||
) => {
|
||||
const { enableIpv6 = true } = options;
|
||||
|
||||
const allowedIps = [
|
||||
`${client.ipv4Address}/32`,
|
||||
`${client.ipv6Address}/128`,
|
||||
...(enableIpv6 ? [`${client.ipv6Address}/128`] : []),
|
||||
...(client.serverAllowedIps ?? []),
|
||||
];
|
||||
|
||||
@@ -25,19 +34,29 @@ PresharedKey = ${client.preSharedKey}
|
||||
AllowedIPs = ${allowedIps.join(', ')}${extraLines.length ? `\n${extraLines.join('\n')}` : ''}`;
|
||||
},
|
||||
|
||||
generateServerInterface: (wgInterface: InterfaceType, hooks: HooksType) => {
|
||||
generateServerInterface: (
|
||||
wgInterface: InterfaceType,
|
||||
hooks: HooksType,
|
||||
options: Options = {}
|
||||
) => {
|
||||
const { enableIpv6 = true } = options;
|
||||
|
||||
const cidr4 = parseCidr(wgInterface.ipv4Cidr);
|
||||
const cidr6 = parseCidr(wgInterface.ipv6Cidr);
|
||||
const ipv4Addr = stringifyIp({ number: cidr4.start + 1n, version: 4 });
|
||||
const ipv6Addr = stringifyIp({ number: cidr6.start + 1n, version: 6 });
|
||||
|
||||
const address =
|
||||
`${ipv4Addr}/${cidr4.prefix}` +
|
||||
(enableIpv6 ? `, ${ipv6Addr}/${cidr6.prefix}` : '');
|
||||
|
||||
return `# Note: Do not edit this file directly.
|
||||
# Your changes will be overwritten!
|
||||
|
||||
# Server
|
||||
[Interface]
|
||||
PrivateKey = ${wgInterface.privateKey}
|
||||
Address = ${ipv4Addr}/${cidr4.prefix}, ${ipv6Addr}/${cidr6.prefix}
|
||||
Address = ${address}
|
||||
ListenPort = ${wgInterface.port}
|
||||
MTU = ${wgInterface.mtu}
|
||||
PreUp = ${iptablesTemplate(hooks.preUp, wgInterface)}
|
||||
@@ -49,11 +68,18 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`;
|
||||
generateClientConfig: (
|
||||
wgInterface: InterfaceType,
|
||||
userConfig: UserConfigType,
|
||||
client: ClientType
|
||||
client: ClientType,
|
||||
options: Options = {}
|
||||
) => {
|
||||
const { enableIpv6 = true } = options;
|
||||
|
||||
const cidr4Block = parseCidr(wgInterface.ipv4Cidr).prefix;
|
||||
const cidr6Block = parseCidr(wgInterface.ipv6Cidr).prefix;
|
||||
|
||||
const address =
|
||||
`${client.ipv4Address}/${cidr4Block}` +
|
||||
(enableIpv6 ? `, ${client.ipv6Address}/${cidr6Block}` : '');
|
||||
|
||||
const hookLines = [
|
||||
client.preUp ? `PreUp = ${client.preUp}` : null,
|
||||
client.postUp ? `PostUp = ${client.postUp}` : null,
|
||||
@@ -63,7 +89,7 @@ PostDown = ${iptablesTemplate(hooks.postDown, wgInterface)}`;
|
||||
|
||||
return `[Interface]
|
||||
PrivateKey = ${client.privateKey}
|
||||
Address = ${client.ipv4Address}/${cidr4Block}, ${client.ipv6Address}/${cidr6Block}
|
||||
Address = ${address}
|
||||
DNS = ${(client.dns ?? userConfig.defaultDns).join(', ')}
|
||||
MTU = ${client.mtu}
|
||||
${hookLines.length ? `${hookLines.join('\n')}\n` : ''}
|
||||
|
||||
Reference in New Issue
Block a user