Cleanup old stuff

This commit is contained in:
root 2025-02-04 12:57:06 +01:00
parent c9b0c2c526
commit 65590f4c62
19 changed files with 169 additions and 264 deletions

View File

@ -58,8 +58,8 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-X 'm
# Release stage
FROM alpine:3.19
RUN addgroup -S wgui && \
adduser -S -D -G wgui wgui
RUN addgroup -S wgm && \
adduser -S -D -G wgm wgm
RUN apk --no-cache add ca-certificates wireguard-tools jq iptables
@ -68,7 +68,7 @@ WORKDIR /app
RUN mkdir -p db
# Copy binary files
COPY --from=builder --chown=wgui:wgui /build/wg-ui .
COPY --from=builder --chown=wgm:wgm /build/wg-ui .
RUN chmod +x wg-ui
COPY init.sh .
RUN chmod +x init.sh

138
README.md
View File

@ -45,23 +45,23 @@ docker-compose up
| `SESSION_SECRET_FILE` | Optional filepath for the secret key used to encrypt the session cookies. Leave `SESSION_SECRET` blank to take effect | N/A |
| `SESSION_MAX_DURATION` | Max time in days a remembered session is refreshed and valid. Non-refreshed session is valid for 7 days max, regardless of this setting. | 90 |
| `SUBNET_RANGES` | The list of address subdivision ranges. Format: `SR Name:10.0.1.0/24; SR2:10.0.2.0/24,10.0.3.0/24` Each CIDR must be inside one of the server interfaces. | N/A |
| `WGUI_USERNAME` | The username for the login page. Used for db initialization only | `admin` |
| `WGUI_PASSWORD` | The password for the user on the login page. Will be hashed automatically. Used for db initialization only | `admin` |
| `WGUI_PASSWORD_FILE` | Optional filepath for the user login password. Will be hashed automatically. Used for db initialization only. Leave `WGUI_PASSWORD` blank to take effect | N/A |
| `WGUI_PASSWORD_HASH` | The password hash for the user on the login page. (alternative to `WGUI_PASSWORD`). Used for db initialization only | N/A |
| `WGUI_PASSWORD_HASH_FILE` | Optional filepath for the user login password hash. (alternative to `WGUI_PASSWORD_FILE`). Used for db initialization only. Leave `WGUI_PASSWORD_HASH` blank to take effect | N/A |
| `WGUI_ENDPOINT_ADDRESS` | The default endpoint address used in global settings where clients should connect to. The endpoint can contain a port as well, useful when you are listening internally on the `WGUI_SERVER_LISTEN_PORT` port, but you forward on another port (ex 9000). Ex: myvpn.dyndns.com:9000 | Resolved to your public ip address |
| `WGUI_FAVICON_FILE_PATH` | The file path used as website favicon | Embedded WireGuard logo |
| `WGUI_DNS` | The default DNS servers (comma-separated-list) used in the global settings | `1.1.1.1` |
| `WGUI_MTU` | The default MTU used in global settings | `1450` |
| `WGUI_PERSISTENT_KEEPALIVE` | The default persistent keepalive for WireGuard in global settings | `15` |
| `WGUI_FIREWALL_MARK` | The default WireGuard firewall mark | `0xca6c` (51820) |
| `WGUI_TABLE` | The default WireGuard table value settings | `auto` |
| `WGUI_CONFIG_FILE_PATH` | The default WireGuard config file path used in global settings | `/etc/wireguard/wg0.conf` |
| `WGUI_LOG_LEVEL` | The default log level. Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` | `INFO` |
| `WGM_USERNAME` | The username for the login page. Used for db initialization only | `admin` |
| `WGM_PASSWORD` | The password for the user on the login page. Will be hashed automatically. Used for db initialization only | `admin` |
| `WGM_PASSWORD_FILE` | Optional filepath for the user login password. Will be hashed automatically. Used for db initialization only. Leave `WGM_PASSWORD` blank to take effect | N/A |
| `WGM_PASSWORD_HASH` | The password hash for the user on the login page. (alternative to `WGM_PASSWORD`). Used for db initialization only | N/A |
| `WGM_PASSWORD_HASH_FILE` | Optional filepath for the user login password hash. (alternative to `WGM_PASSWORD_FILE`). Used for db initialization only. Leave `WGM_PASSWORD_HASH` blank to take effect | N/A |
| `WGM_ENDPOINT_ADDRESS` | The default endpoint address used in global settings where clients should connect to. The endpoint can contain a port as well, useful when you are listening internally on the `WGM_SERVER_LISTEN_PORT` port, but you forward on another port (ex 9000). Ex: myvpn.dyndns.com:9000 | Resolved to your public ip address |
| `WGM_FAVICON_FILE_PATH` | The file path used as website favicon | Embedded WireGuard logo |
| `WGM_DNS` | The default DNS servers (comma-separated-list) used in the global settings | `1.1.1.1` |
| `WGM_MTU` | The default MTU used in global settings | `1450` |
| `WGM_PERSISTENT_KEEPALIVE` | The default persistent keepalive for WireGuard in global settings | `15` |
| `WGM_FIREWALL_MARK` | The default WireGuard firewall mark | `0xca6c` (51820) |
| `WGM_TABLE` | The default WireGuard table value settings | `auto` |
| `WGM_CONFIG_FILE_PATH` | The default WireGuard config file path used in global settings | `/etc/wireguard/wg0.conf` |
| `WGM_LOG_LEVEL` | The default log level. Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` | `INFO` |
| `WG_CONF_TEMPLATE` | The custom `wg.conf` config file template. Please refer to our [default template](https://github.com/swissmakers/wireguard-manager/blob/master/templates/wg.conf) | N/A |
| `EMAIL_FROM_ADDRESS` | The sender email address | N/A |
| `EMAIL_FROM_NAME` | The sender name | `WireGuard UI` |
| `EMAIL_FROM_NAME` | The sender name | `WireGuard Manager` |
| `SENDGRID_API_KEY` | The SendGrid api key | N/A |
| `SENDGRID_API_KEY_FILE` | Optional filepath for the SendGrid api key. Leave `SENDGRID_API_KEY` blank to take effect | N/A |
| `SMTP_HOSTNAME` | The SMTP IP address or hostname | `127.0.0.1` |
@ -82,10 +82,10 @@ These environment variables are used to control the default server settings used
| Variable | Description | Default |
|-----------------------------------|-----------------------------------------------------------------------------------------------|-----------------|
| `WGUI_SERVER_INTERFACE_ADDRESSES` | The default interface addresses (comma-separated-list) for the WireGuard server configuration | `10.252.1.0/24` |
| `WGUI_SERVER_LISTEN_PORT` | The default server listen port | `51820` |
| `WGUI_SERVER_POST_UP_SCRIPT` | The default server post-up script | N/A |
| `WGUI_SERVER_POST_DOWN_SCRIPT` | The default server post-down script | N/A |
| `WGM_SERVER_INTERFACE_ADDRESSES` | The default interface addresses (comma-separated-list) for the WireGuard server configuration | `10.252.1.0/24` |
| `WGM_SERVER_LISTEN_PORT` | The default server listen port | `51820` |
| `WGM_SERVER_POST_UP_SCRIPT` | The default server post-up script | N/A |
| `WGM_SERVER_POST_DOWN_SCRIPT` | The default server post-down script | N/A |
### Defaults for new clients
@ -93,10 +93,10 @@ These environment variables are used to set the defaults used in `New Client` di
| Variable | Description | Default |
|---------------------------------------------|-------------------------------------------------------------------------------------------------|-------------|
| `WGUI_DEFAULT_CLIENT_ALLOWED_IPS` | Comma-separated-list of CIDRs for the `Allowed IPs` field. (default ) | `0.0.0.0/0` |
| `WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS` | Comma-separated-list of CIDRs for the `Extra Allowed IPs` field. (default empty) | N/A |
| `WGUI_DEFAULT_CLIENT_USE_SERVER_DNS` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] | `true` |
| `WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] | `true` |
| `WGM_DEFAULT_CLIENT_ALLOWED_IPS` | Comma-separated-list of CIDRs for the `Allowed IPs` field. (default ) | `0.0.0.0/0` |
| `WGM_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS` | Comma-separated-list of CIDRs for the `Extra Allowed IPs` field. (default empty) | N/A |
| `WGM_DEFAULT_CLIENT_USE_SERVER_DNS` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] | `true` |
| `WGM_DEFAULT_CLIENT_ENABLE_AFTER_CREATION` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] | `true` |
### Docker only
@ -104,9 +104,9 @@ These environment variables only apply to the docker container.
| Variable | Description | Default |
|-----------------------|---------------------------------------------------------------|---------|
| `WGUI_MANAGE_START` | Start/stop WireGuard when the container is started/stopped | `false` |
| `WGUI_MANAGE_RESTART` | Auto restart WireGuard when we Apply Config changes in the UI | `false` |
| `WGUI_MANAGE_RELOAD` | Auto reload WireGuard when we Apply Config changes in the UI | `false` |
| `WGM_MANAGE_START` | Start/stop WireGuard when the container is started/stopped | `false` |
| `WGM_MANAGE_RESTART` | Auto restart WireGuard when we Apply Config changes in the UI | `false` |
| `WGM_MANAGE_RELOAD` | Auto reload WireGuard when we Apply Config changes in the UI | `false` |
## Auto restart WireGuard daemon
@ -115,31 +115,31 @@ service. Following is an example:
### Using systemd
#### Create dedicated wireguard-ui user
#### Create dedicated wireguard-manager user
```bash
useradd -m -r -s /bin/false -d /var/lib/wireguard-ui wireguard-ui
useradd -m -r -s /bin/false -d /var/lib/wireguard-manager wireguard-manager
```
#### Create wireguard config file and set permission with Linux ACL
```bash
touch /etc/wireguard/wg0.conf
setfacl -m wireguard-ui:rw /etc/wireguard/wg0.conf
setfacl -m wireguard-manager:rw /etc/wireguard/wg0.conf
```
#### Create environment file for wireguard-ui
```/etc/wireguard-ui/environment.conf```
#### Create environment file for wireguard-manager
```/etc/wireguard-manager/environment.conf```
```env
BASE_PATH="/"
BIND_ADDRESS="127.0.0.1:5000"
SESSION_SECRET="veryS3cr3t"
WGUI_USERNAME="admin"
WGUI_PASSWORD="my+password"
WGUI_ENDPOINT_ADDRESS="vpn.example.com"
WGUI_DNS="1.1.1.1"
WGUI_MTU="1450"
WGUI_PERSISTENT_KEEPALIVE="15"
WGUI_CONFIG_FILE_PATH="/etc/wireguard/wg0.conf"
WGUI_LOG_LEVEL="DEBUG"
WGM_USERNAME="admin"
WGM_PASSWORD="my+password"
WGM_ENDPOINT_ADDRESS="vpn.example.com"
WGM_DNS="1.1.1.1"
WGM_MTU="1450"
WGM_PERSISTENT_KEEPALIVE="15"
WGM_CONFIG_FILE_PATH="/etc/wireguard/wg0.conf"
WGM_LOG_LEVEL="DEBUG"
# WG_CONF_TEMPLATE=
# EMAIL_FROM_ADDRESS=
# EMAIL_FROM_NAME=
@ -152,26 +152,26 @@ WGUI_LOG_LEVEL="DEBUG"
# SMTP_ENCRYPTION=
```
#### Create systemd service for wireguard-ui
```/etc/systemd/system/wireguard-ui.service```
#### Create systemd service for wireguard-manager
```/etc/systemd/system/wireguard-manager.service```
```bash
[Unit]
Description=WireGuard UI
ConditionPathExists=/var/lib/wireguard-ui
Description=WireGuard Manager
ConditionPathExists=/var/lib/wireguard-manager
After=network.target
[Service]
Type=simple
User=wireguard-ui
Group=wireguard-ui
User=wireguard-manager
Group=wireguard-manager
CapabilityBoundingSet=CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW
AmbientCapabilities=CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW
WorkingDirectory=/var/lib/wireguard-ui
EnvironmentFile=/etc/wireguard-ui/environment.conf
ExecStart=/usr/local/share/applications/wireguard-ui
WorkingDirectory=/var/lib/wireguard-manager
EnvironmentFile=/etc/wireguard-manager/environment.conf
ExecStart=/usr/local/share/applications/wireguard-manager
Restart=on-failure
RestartSec=10
@ -181,11 +181,11 @@ WantedBy=multi-user.target
```
#### TODO (maybe delete)
Create `/etc/systemd/system/wgui.service`
Create `/etc/systemd/system/wgm.service`
```bash
cd /etc/systemd/system/
cat << EOF > wgui.service
cat << EOF > wgm.service
[Unit]
Description=Restart WireGuard
After=network.target
@ -195,15 +195,15 @@ Type=oneshot
ExecStart=/usr/bin/systemctl restart wg-quick@wg0.service
[Install]
RequiredBy=wgui.path
RequiredBy=wgm.path
EOF
```
Create `/etc/systemd/system/wgui.path`
Create `/etc/systemd/system/wgm.path`
```bash
cd /etc/systemd/system/
cat << EOF > wgui.path
cat << EOF > wgm.path
[Unit]
Description=Watch /etc/wireguard/wg0.conf for changes
@ -218,56 +218,56 @@ EOF
Apply it
```sh
systemctl enable wgui.{path,service}
systemctl start wgui.{path,service}
systemctl enable wgm.{path,service}
systemctl start wgm.{path,service}
```
### Using openrc
Create `/usr/local/bin/wgui` file and make it executable
Create `/usr/local/bin/wgm` file and make it executable
```sh
cd /usr/local/bin/
cat << EOF > wgui
cat << EOF > wgm
#!/bin/sh
wg-quick down wg0
wg-quick up wg0
EOF
chmod +x wgui
chmod +x wgm
```
Create `/etc/init.d/wgui` file and make it executable
Create `/etc/init.d/wgm` file and make it executable
```sh
cd /etc/init.d/
cat << EOF > wgui
cat << EOF > wgm
#!/sbin/openrc-run
command=/sbin/inotifyd
command_args="/usr/local/bin/wgui /etc/wireguard/wg0.conf:w"
command_args="/usr/local/bin/wgm /etc/wireguard/wg0.conf:w"
pidfile=/run/${RC_SVCNAME}.pid
command_background=yes
EOF
chmod +x wgui
chmod +x wgm
```
Apply it
```sh
rc-service wgui start
rc-update add wgui default
rc-service wgm start
rc-update add wgm default
```
### Using Docker
Set `WGUI_MANAGE_RESTART=true` to manage Wireguard interface restarts.
Using `WGUI_MANAGE_START=true` can also replace the function of `wg-quick@wg0` service, to start Wireguard at boot, by
running the container with `restart: unless-stopped`. These settings can also pick up changes to Wireguard Config File
Set `WGM_MANAGE_RESTART=true` to manage WireGuard interface restarts.
Using `WGM_MANAGE_START=true` can also replace the function of `wg-quick@wg0` service, to start WireGuard at boot, by
running the container with `restart: unless-stopped`. These settings can also pick up changes to WireGuard Config File
Path, after restarting the container. Please make sure you have `--cap-add=NET_ADMIN` in your container config to make
this feature work.
Set `WGUI_MANAGE_RELOAD=true` to manage WireGuard interface reload.
Using `WGUI_MANAGE_RELOAD=true` will use `wg syncconf wg0 /path/to/file` to update the WireGuard running-configuration
Set `WGM_MANAGE_RELOAD=true` to manage WireGuard interface reload.
Using `WGM_MANAGE_RELOAD=true` will use `wg syncconf wg0 /path/to/file` to update the WireGuard running-configuration
without restart. Please make sure you have `--cap-add=NET_ADMIN` in your container config to make this feature work.
## Build

View File

@ -4,7 +4,7 @@ services:
wg:
build: .
#image: swissmakers/wireguard-manager:latest
container_name: wgui
container_name: wgm
cap_add:
- NET_ADMIN
network_mode: host
@ -13,11 +13,11 @@ services:
- EMAIL_FROM_ADDRESS
- EMAIL_FROM_NAME
- SESSION_SECRET
- WGUI_USERNAME=alpha
- WGUI_PASSWORD=this-unusual-password
- WGM_USERNAME=alpha
- WGM_PASSWORD=this-unusual-password
- WG_CONF_TEMPLATE
- WGUI_MANAGE_START=false
- WGUI_MANAGE_RESTART=false
- WGM_MANAGE_START=false
- WGM_MANAGE_RESTART=false
logging:
driver: json-file
options:

View File

@ -2,7 +2,7 @@
### Kernel Module
Depending on if the Wireguard kernel module is available on your system you have more or less choices which example to use.
Depending on if the WireGuard kernel module is available on your system you have more or less choices which example to use.
You can check if the kernel modules are available via the following command:
```shell
@ -21,10 +21,10 @@ For security reasons it's highly recommended to change them before the first sta
## Examples
- **[system](system.yml)**
If you have Wireguard already installed on your system and only want to run the UI in docker this might fit the most.
If you have WireGuard already installed on your system and only want to run the UI in docker this might fit the most.
- **[linuxserver](linuxserver.yml)**
If you have the Wireguard kernel modules installed (included in the mainline kernel since version 5.6) but want it running inside of docker, this might fit the most.
If you have the WireGuard kernel modules installed (included in the mainline kernel since version 5.6) but want it running inside of docker, this might fit the most.
- **[boringtun](boringtun.yml)**
If Wireguard kernel modules are not available, you can switch to an userspace implementation like [boringtun](https://github.com/cloudflare/boringtun).
If WireGuard kernel modules are not available, you can switch to an userspace implementation like [boringtun](https://github.com/cloudflare/boringtun).

View File

@ -24,11 +24,11 @@ services:
- EMAIL_FROM_ADDRESS
- EMAIL_FROM_NAME
- SESSION_SECRET
- WGUI_USERNAME=admin
- WGUI_PASSWORD=admin
- WGM_USERNAME=admin
- WGM_PASSWORD=admin
- WG_CONF_TEMPLATE
- WGUI_MANAGE_START=true
- WGUI_MANAGE_RESTART=true
- WGM_MANAGE_START=true
- WGM_MANAGE_RESTART=true
logging:
driver: json-file
options:

View File

@ -28,11 +28,11 @@ services:
- EMAIL_FROM_ADDRESS
- EMAIL_FROM_NAME
- SESSION_SECRET
- WGUI_USERNAME=admin
- WGUI_PASSWORD=admin
- WGM_USERNAME=admin
- WGM_PASSWORD=admin
- WG_CONF_TEMPLATE
- WGUI_MANAGE_START=true
- WGUI_MANAGE_RESTART=true
- WGM_MANAGE_START=true
- WGM_MANAGE_RESTART=true
logging:
driver: json-file
options:

View File

@ -13,11 +13,11 @@ services:
- EMAIL_FROM_ADDRESS
- EMAIL_FROM_NAME
- SESSION_SECRET
- WGUI_USERNAME=admin
- WGUI_PASSWORD=admin
- WGM_USERNAME=admin
- WGM_PASSWORD=admin
- WG_CONF_TEMPLATE
- WGUI_MANAGE_START=false
- WGUI_MANAGE_RESTART=false
- WGM_MANAGE_START=false
- WGM_MANAGE_RESTART=false
logging:
driver: json-file
options:

View File

@ -371,7 +371,7 @@ func WireGuardClients(db store.IStore) echo.HandlerFunc {
}
}
// GetClients handler return a JSON list of Wireguard client data
// GetClients handler return a JSON list of WireGuard client data
func GetClients(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
clientDataList, err := db.GetClients(true)
@ -389,7 +389,7 @@ func GetClients(db store.IStore) echo.HandlerFunc {
}
}
// GetClient handler returns a JSON object of Wireguard client data
// GetClient handler returns a JSON object of WireGuard client data
func GetClient(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
clientID := c.Param("id")
@ -460,12 +460,12 @@ func NewClient(db store.IStore) echo.HandlerFunc {
guid := xid.New()
client.ID = guid.String()
// gen Wireguard key pair
// gen WireGuard key pair
if client.PublicKey == "" {
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
log.Error("Cannot generate wireguard key pair: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate WireGuard key pair"})
}
client.PrivateKey = key.String()
client.PublicKey = key.PublicKey().String()
@ -473,7 +473,7 @@ func NewClient(db store.IStore) echo.HandlerFunc {
_, err := wgtypes.ParseKey(client.PublicKey)
if err != nil {
log.Error("Cannot verify wireguard public key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify Wireguard public key"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify WireGuard public key"})
}
// check for duplicates
clients, err := db.GetClients(false)
@ -494,7 +494,7 @@ func NewClient(db store.IStore) echo.HandlerFunc {
if err != nil {
log.Error("Cannot generated preshared key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
false, "Cannot generate Wireguard preshared key",
false, "Cannot generate WireGuard preshared key",
})
}
client.PresharedKey = presharedKey.String()
@ -505,7 +505,7 @@ func NewClient(db store.IStore) echo.HandlerFunc {
_, err := wgtypes.ParseKey(client.PresharedKey)
if err != nil {
log.Error("Cannot verify wireguard preshared key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify Wireguard preshared key"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify WireGuard preshared key"})
}
}
client.CreatedAt = time.Now().UTC()
@ -680,12 +680,12 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Extra Allowed IPs must be in CIDR format"})
}
// update Wireguard Client PublicKey
// update WireGuard Client PublicKey
if client.PublicKey != _client.PublicKey && _client.PublicKey != "" {
_, err := wgtypes.ParseKey(_client.PublicKey)
if err != nil {
log.Error("Cannot verify provided Wireguard public key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided Wireguard public key"})
log.Error("Cannot verify provided WireGuard public key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided WireGuard public key"})
}
// check for duplicates
clients, err := db.GetClients(false)
@ -700,7 +700,7 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
}
}
// When replacing any PublicKey, discard any locally stored Wireguard Client PrivateKey
// When replacing any PublicKey, discard any locally stored WireGuard Client PrivateKey
// Client PubKey no longer corresponds to locally stored PrivKey.
// QR code (needs PrivateKey) for this client is no longer possible now.
@ -709,12 +709,12 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
}
}
// update Wireguard Client PresharedKey
// update WireGuard Client PresharedKey
if client.PresharedKey != _client.PresharedKey && _client.PresharedKey != "" {
_, err := wgtypes.ParseKey(_client.PresharedKey)
if err != nil {
log.Error("Cannot verify provided Wireguard preshared key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided Wireguard preshared key"})
log.Error("Cannot verify provided WireGuard preshared key: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided WireGuard preshared key"})
}
}
@ -881,11 +881,11 @@ func WireGuardServerInterfaces(db store.IStore) echo.HandlerFunc {
// WireGuardServerKeyPair handler to generate private and public keys
func WireGuardServerKeyPair(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
// gen Wireguard key pair
// gen WireGuard key pair
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
log.Error("Cannot generate wireguard key pair: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate WireGuard key pair"})
}
var serverKeyPair model.ServerKeypair
@ -894,7 +894,7 @@ func WireGuardServerKeyPair(db store.IStore) echo.HandlerFunc {
serverKeyPair.UpdatedAt = time.Now().UTC()
if err := db.SaveServerKeyPair(serverKeyPair); err != nil {
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate WireGuard key pair"})
}
log.Infof("Updated wireguard server interfaces settings: %v", serverKeyPair)
@ -1033,7 +1033,7 @@ func GlobalSettingSubmit(db store.IStore) echo.HandlerFunc {
// write config to the database
if err := db.SaveGlobalSettings(globalSettings); err != nil {
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate WireGuard key pair"})
}
log.Infof("Updated global settings: %v", globalSettings)
@ -1138,7 +1138,7 @@ func SuggestIPAllocation(db store.IStore) echo.HandlerFunc {
}
}
// ApplyServerConfig handler to write config file and restart Wireguard server
// ApplyServerConfig handler to write config file and restart WireGuard server
func ApplyServerConfig(db store.IStore, tmplDir fs.FS) echo.HandlerFunc {
return func(c echo.Context) error {
server, err := db.GetServer()

View File

@ -4,13 +4,13 @@
conf="$(jq -r .config_file_path db/server/global_settings.json || echo /etc/wireguard/wg0.conf)"
# manage wireguard stop/start with the container
case $WGUI_MANAGE_START in (1|t|T|true|True|TRUE)
case $WGM_MANAGE_START in (1|t|T|true|True|TRUE)
wg-quick up "$conf"
trap 'wg-quick down "$conf"' SIGTERM # catches container stop
esac
# manage wireguard restarts
case $WGUI_MANAGE_RESTART in (1|t|T|true|True|TRUE)
case $WGM_MANAGE_RESTART in (1|t|T|true|True|TRUE)
[[ -f $conf ]] || touch "$conf" # inotifyd needs file to exist
inotifyd - "$conf":w | while read -r event file; do
wg-quick down "$file"
@ -19,7 +19,7 @@ case $WGUI_MANAGE_RESTART in (1|t|T|true|True|TRUE)
esac
# manage wireguard reload
case $WGUI_MANAGE_RELOAD in (1|t|T|true|True|TRUE)
case $WGM_MANAGE_RELOAD in (1|t|T|true|True|TRUE)
[[ -f $conf ]] || touch "$conf" # inotifyd needs file to exist
inotifyd - "$conf":w | while read -r event file; do
wg syncconf wg0 <(wg-quick strip wg0)

View File

@ -27,7 +27,7 @@ import (
var (
// command-line banner information
appVersion = "development"
appVersion = "stable"
gitCommit = "N/A"
gitRef = "N/A"
buildTime = time.Now().UTC().Format("01-02-2006 15:04:05")
@ -46,7 +46,7 @@ var (
flagSmtpHelo = "localhost"
flagSendgridApiKey string
flagEmailFrom string
flagEmailFromName = "WireGuard UI"
flagEmailFromName = "WireGuard Manager"
flagTelegramToken string
flagTelegramAllowConfRequest = false
flagTelegramFloodWait = 60
@ -158,7 +158,7 @@ func init() {
// print only if log level is INFO or lower
if lvl <= log.INFO {
// print app information
fmt.Println("Wireguard UI")
fmt.Println("WireGuard Manager")
fmt.Println("App Version\t:", appVersion)
fmt.Println("Git Commit\t:", gitCommit)
fmt.Println("Git Ref\t\t:", gitRef)

View File

@ -1,7 +1,7 @@
{
"name": "wireguard-manager",
"version": "0.0.1",
"description": "A Wireguard web-interface",
"description": "A WireGuard web-interface",
"main": "index.js",
"repository": "git@github.com:swissmakers/wireguard-manager.git",
"author": "Swissmakers GmbH <info@swissmakers.ch>",

View File

@ -22,7 +22,7 @@ About
<div class="col-md-6">
<div class="card card-success">
<div class="card-header">
<h3 class="card-title">About Wireguard-UI</h3>
<h3 class="card-title">About WireGuard-Manager</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
@ -36,34 +36,9 @@ About
<input type="text" class="form-control" id="version" value="{{ .gitCommit }}" readonly>
</div>
{{ end }}
<div class="form-group">
<label for="currentReleaseDate" class="control-label">Current version release date</label>
<input type="text" class="form-control" id="currentReleaseDate" readonly>
</div>
<div class="form-group">
<label for="latestRelease" class="control-label">Latest release</label>
<input type="text" class="form-control" id="latestRelease" readonly>
</div>
<div class="form-group">
<label for="latestReleaseDate" class="control-label">Latest release date</label>
<input type="text" class="form-control" id="latestReleaseDate" readonly>
</div>
<div class="form-group">
<label for="author" class="control-label">Author</label>
<div id="author">
<a id="authorLink">
<img id="authorImage"
style="width: 50px; height: 50px; border-radius: 50%; border: 1px solid #000;">
</a>
</div>
</div>
<div class="form-group">
<label for="contributors" class="control-label">Contributors</label>
<div id="contributors"></div>
</div>
<strong>Copyright &copy;
<script>document.write(new Date().getFullYear())</script>
<a href="https://github.com/swissmakers/wireguard-manager">Wireguard UI</a>.
<a href="https://github.com/swissmakers/wireguard-manager">WireGuard Manager</a>.
</strong> All rights reserved.
</div>
@ -78,68 +53,6 @@ About
{{ define "bottom_js"}}
<script>
$(document).ready(function () {
$.ajax({
cache: false,
method: 'GET',
url: 'https://api.github.com/repos/swissmakers/wireguard-manager/releases/tags/' + $("#version").val(),
dataType: 'json',
contentType: "application/json",
success: function (data) {
$("#currentReleaseDate").attr("value", data.published_at.split("T")[0]);
},
error: function (jqXHR, exception) {
$("#currentReleaseDate").attr("value", "Could not find this version on GitHub.com");
}
});
$.ajax({
cache: false,
method: 'GET',
url: 'https://api.github.com/repos/swissmakers/wireguard-manager/releases/latest',
dataType: 'json',
contentType: "application/json",
success: function (data) {
$("#latestRelease").attr("value", data.tag_name);
$("#latestReleaseDate").attr("value", data.published_at.split("T")[0]);
$("#author").attr("value", data.author.login);
$("#authorImage").attr("src", data.author.avatar_url);
$("#authorImage").after("<b> " + data.author.login + "</b>");
$("#authorLink").attr("href", data.author.html_url);
},
error: function (jqXHR, exception) {
$("#latestRelease").attr("value", "Could not connect to GitHub.com");
$("#latestReleaseDate").attr("value", "Could not connect to GitHub.com");
$("#author").attr("value", "Could not connect to GitHub.com");
}
});
$.ajax({
cache: false,
method: 'GET',
url: 'https://api.github.com/repos/swissmakers/wireguard-manager/contributors',
dataType: 'json',
contentType: "application/json",
success: function (data) {
data.forEach(contributor => $("#contributors").append("<a href=\"" + contributor.html_url + "\" title=\"" + contributor.login + "\">" +
"<img src=\"" + contributor.avatar_url + "\" style=\"width: 50px; height: 50px; border-radius: 50%; border: 1px solid #000; margin: 5px;\"/></a>"));
},
error: function (jqXHR, exception) {
$("#contributors").html("<p>Could not connect to GitHub.com</p>");
}
});
});
$(document).ajaxStop(function () {
if (Date.parse($("#currentReleaseDate").val()) < Date.parse($("#latestReleaseDate").val())) {
$("#currentReleaseDate").after("<p style=\"color:red\">Current version is out of date</p>")
}
});
</script>
{{ end }}

View File

@ -21,12 +21,8 @@
<link rel="stylesheet" href="{{.basePath}}/static/plugins/toastr/toastr.min.css">
<!-- Jquery Tags Input -->
<link rel="stylesheet" href="{{.basePath}}/static/plugins/jquery-tags-input/dist/jquery.tagsinput.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- overlayScrollbars -->
<link rel="stylesheet" href="{{.basePath}}/static/dist/css/adminlte.min.css">
<!-- Google Font: Source Sans Pro -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
<!-- START: On page css -->
{{template "top_css" .}}
@ -122,7 +118,7 @@
<a href="{{.basePath}}/" class="nav-link {{if eq .baseData.Active ""}}active{{end}}">
<i class="nav-icon fas fa-user-secret"></i>
<p>
Wireguard Clients
WireGuard Clients
</p>
</a>
</li>
@ -132,7 +128,7 @@
<a href="{{.basePath}}/wg-server" class="nav-link {{if eq .baseData.Active "wg-server" }}active{{end}}">
<i class="nav-icon fas fa-server"></i>
<p>
Wireguard Server
WireGuard Server
</p>
</a>
</li>
@ -196,7 +192,7 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">New Wireguard Client</h4>
<h4 class="modal-title">New WireGuard Client</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
@ -352,7 +348,7 @@
<div class="float-right d-none d-sm-block">
<b>Version</b> {{ .appVersion }}
</div>
<strong>Copyright &copy; <script>document.write(new Date().getFullYear())</script> <a href="https://github.com/swissmakers/wireguard-manager">Wireguard UI</a>.</strong> All rights
<strong>Copyright &copy; <script>document.write(new Date().getFullYear())</script> <a href="https://github.com/swissmakers/wireguard-manager">WireGuard Manager</a>.</strong> All rights
reserved.
</footer>
-->

View File

@ -1,5 +1,5 @@
{{define "title"}}
Wireguard Clients
WireGuard Clients
{{end}}
{{define "top_css"}}
@ -17,13 +17,13 @@ Wireguard Clients
{{end}}
{{define "page_title"}}
Wireguard Clients
WireGuard Clients
{{end}}
{{define "page_content"}}
<section class="content">
<div class="container-fluid">
<!-- <h5 class="mt-4 mb-2">Wireguard Clients</h5> -->
<!-- <h5 class="mt-4 mb-2">WireGuard Clients</h5> -->
<div class="row" id="client-list">
</div>
<!-- /.row -->

View File

@ -22,7 +22,7 @@ Global Settings
<div class="col-md-6">
<div class="card card-success">
<div class="card-header">
<h3 class="card-title">Wireguard Global Settings</h3>
<h3 class="card-title">WireGuard Global Settings</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
@ -68,7 +68,7 @@ Global Settings
value="{{ .globalSettings.Table }}">
</div>
<div class="form-group">
<label for="config_file_path">Wireguard Config File Path</label>
<label for="config_file_path">WireGuard Config File Path</label>
<input type="text" class="form-control" id="config_file_path"
name="config_file_path" placeholder="E.g. /etc/wireguard/wg0.conf"
value="{{ .globalSettings.ConfigFilePath }}">
@ -92,7 +92,7 @@ Global Settings
<div class="card-body">
<dl>
<dt>1. Endpoint Address</dt>
<dd>The public IP address of your Wireguard server that the client will connect to. Click on
<dd>The public IP address of your WireGuard server that the client will connect to. Click on
<strong>Suggest</strong> button to auto detect the public IP address of your server.</dd>
<dt>2. DNS Servers</dt>
<dd>The DNS servers will be set to client config.</dd>
@ -110,8 +110,8 @@ Global Settings
<dd>Add a matching <code>fwmark</code> on all packets going out of a WireGuard non-default-route tunnel. Default value: <code>0xca6c</code></dd>
<dt>6. Table</dt>
<dd>Value for the <code>Table</code> setting in the wg conf file. Default value: <code>auto</code></dd>
<dt>7. Wireguard Config File Path</dt>
<dd>The path of your Wireguard server config file. Please make sure the parent directory
<dt>7. WireGuard Config File Path</dt>
<dd>The path of your WireGuard server config file. Please make sure the parent directory
exists and is writable.</dd>
</dl>
</div>
@ -195,7 +195,7 @@ Global Settings
}
</script>
<script>
// Wireguard Interface DNS server tag input
// WireGuard Interface DNS server tag input
$("#dns_servers").tagsInput({
'width': '100%',
'height': '75%',

View File

@ -12,14 +12,10 @@
<!-- Font Awesome -->
<link rel="stylesheet" href="{{.basePath}}/static/plugins/fontawesome-free/css/all.min.css">
<!-- Ionicons -->
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<!-- icheck bootstrap -->
<link rel="stylesheet" href="{{.basePath}}/static/plugins/icheck-bootstrap/icheck-bootstrap.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="{{.basePath}}/static/dist/css/adminlte.min.css">
<!-- Google Font: Source Sans Pro -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
</head>
<body class="hold-transition login-page">

View File

@ -1,5 +1,5 @@
{{define "title"}}
Wireguard Server
WireGuard Server
{{end}}
{{define "top_css"}}
@ -10,13 +10,13 @@ Wireguard Server
{{end}}
{{define "page_title"}}
Wireguard Server Settings
WireGuard Server Settings
{{end}}
{{define "page_content"}}
<section class="content">
<div class="container-fluid">
<!-- <h5 class="mt-4 mb-2">Wireguard Server</h5> -->
<!-- <h5 class="mt-4 mb-2">WireGuard Server</h5> -->
<div class="row">
<!-- left column -->
<div class="col-md-6">
@ -115,7 +115,7 @@ Wireguard Server Settings
</button>
</div>
<div class="modal-body">
<p>Are you sure to generate a new key pair for the Wireguard server?<br/>
<p>Are you sure to generate a new key pair for the WireGuard server?<br/>
The existing Client's peer public key need to be updated to keep the connection working.</p>
</div>
<div class="modal-footer justify-content-between">
@ -149,7 +149,7 @@ Wireguard Server Settings
data: JSON.stringify(data),
success: function(data) {
$("#modal_new_client").modal('hide');
toastr.success('Updated Wireguard server interface addresses successfully');
toastr.success('Updated WireGuard server interface addresses successfully');
},
error: function(jqXHR, exception) {
const responseJson = jQuery.parseJSON(jqXHR.responseText);
@ -159,7 +159,7 @@ Wireguard Server Settings
}
</script>
<script>
// Wireguard Interface Addresses tag input
// WireGuard Interface Addresses tag input
$("#addresses").tagsInput({
'width': '100%',
// 'height': '75%',
@ -177,7 +177,7 @@ Wireguard Server Settings
$("#addresses").addTag('{{.}}');
{{end}}
// Wireguard Interface Addresses form validation
// WireGuard Interface Addresses form validation
$(document).ready(function () {
$.validator.setDefaults({
submitHandler: function () {
@ -213,7 +213,7 @@ Wireguard Server Settings
});
});
// Wireguard Key Pair generation confirmation button
// WireGuard Key Pair generation confirmation button
$(document).ready(function () {
$("#btn_generate_confirm").click(function () {
$.ajax({

View File

@ -43,28 +43,28 @@ const (
DefaultFirewallMark = "0xca6c" // i.e. 51820
DefaultTable = "auto"
DefaultConfigFilePath = "/etc/wireguard/wg0.conf"
UsernameEnvVar = "WGUI_USERNAME"
PasswordEnvVar = "WGUI_PASSWORD"
PasswordFileEnvVar = "WGUI_PASSWORD_FILE"
PasswordHashEnvVar = "WGUI_PASSWORD_HASH"
PasswordHashFileEnvVar = "WGUI_PASSWORD_HASH_FILE"
FaviconFilePathEnvVar = "WGUI_FAVICON_FILE_PATH"
EndpointAddressEnvVar = "WGUI_ENDPOINT_ADDRESS"
DNSEnvVar = "WGUI_DNS"
MTUEnvVar = "WGUI_MTU"
PersistentKeepaliveEnvVar = "WGUI_PERSISTENT_KEEPALIVE"
FirewallMarkEnvVar = "WGUI_FIREWALL_MARK"
TableEnvVar = "WGUI_TABLE"
ConfigFilePathEnvVar = "WGUI_CONFIG_FILE_PATH"
LogLevel = "WGUI_LOG_LEVEL"
ServerAddressesEnvVar = "WGUI_SERVER_INTERFACE_ADDRESSES"
ServerListenPortEnvVar = "WGUI_SERVER_LISTEN_PORT"
ServerPostUpScriptEnvVar = "WGUI_SERVER_POST_UP_SCRIPT"
ServerPostDownScriptEnvVar = "WGUI_SERVER_POST_DOWN_SCRIPT"
DefaultClientAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_ALLOWED_IPS"
DefaultClientExtraAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS"
DefaultClientUseServerDNSEnvVar = "WGUI_DEFAULT_CLIENT_USE_SERVER_DNS"
DefaultClientEnableAfterCreationEnvVar = "WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION"
UsernameEnvVar = "WGM_USERNAME"
PasswordEnvVar = "WGM_PASSWORD"
PasswordFileEnvVar = "WGM_PASSWORD_FILE"
PasswordHashEnvVar = "WGM_PASSWORD_HASH"
PasswordHashFileEnvVar = "WGM_PASSWORD_HASH_FILE"
FaviconFilePathEnvVar = "WGM_FAVICON_FILE_PATH"
EndpointAddressEnvVar = "WGM_ENDPOINT_ADDRESS"
DNSEnvVar = "WGM_DNS"
MTUEnvVar = "WGM_MTU"
PersistentKeepaliveEnvVar = "WGM_PERSISTENT_KEEPALIVE"
FirewallMarkEnvVar = "WGM_FIREWALL_MARK"
TableEnvVar = "WGM_TABLE"
ConfigFilePathEnvVar = "WGM_CONFIG_FILE_PATH"
LogLevel = "WGM_LOG_LEVEL"
ServerAddressesEnvVar = "WGM_SERVER_INTERFACE_ADDRESSES"
ServerListenPortEnvVar = "WGM_SERVER_LISTEN_PORT"
ServerPostUpScriptEnvVar = "WGM_SERVER_POST_UP_SCRIPT"
ServerPostDownScriptEnvVar = "WGM_SERVER_POST_DOWN_SCRIPT"
DefaultClientAllowedIpsEnvVar = "WGM_DEFAULT_CLIENT_ALLOWED_IPS"
DefaultClientExtraAllowedIpsEnvVar = "WGM_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS"
DefaultClientUseServerDNSEnvVar = "WGM_DEFAULT_CLIENT_USE_SERVER_DNS"
DefaultClientEnableAfterCreationEnvVar = "WGM_DEFAULT_CLIENT_ENABLE_AFTER_CREATION"
)
func ParseBasePath(basePath string) string {

View File

@ -541,9 +541,9 @@ func GetSubnetRangesString() string {
return strings.TrimSpace(strB.String())
}
// WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
// WriteWireGuardServerConfig to write WireGuard server config. e.g. wg0.conf
func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, clientDataList []model.ClientData, usersList []model.User, globalSettings model.GlobalSetting) error {
var tmplWireguardConf string
var tmplWireGuardConf string
// if set, read wg.conf template from WgConfTemplate
if len(WgConfTemplate) > 0 {
@ -551,14 +551,14 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
if err != nil {
return err
}
tmplWireguardConf = string(fileContentBytes)
tmplWireGuardConf = string(fileContentBytes)
} else {
// read default wg.conf template file to string
fileContent, err := StringFromEmbedFile(tmplDir, "wg.conf")
if err != nil {
return err
}
tmplWireguardConf = fileContent
tmplWireGuardConf = fileContent
}
// escape multiline notes
@ -571,7 +571,7 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
}
// parse the template
t, err := template.New("wg_config").Parse(tmplWireguardConf)
t, err := template.New("wg_config").Parse(tmplWireGuardConf)
if err != nil {
return err
}