mirror of
https://github.com/ngoduykhanh/wireguard-ui
synced 2024-06-11 02:12:25 +02:00
Added wireguard service in container
This commit is contained in:
parent
f43c59c043
commit
a13b78b1f5
27
Dockerfile
27
Dockerfile
|
@ -13,11 +13,8 @@ RUN apk add --update --no-cache ${BUILD_DEPENDENCIES}
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
# Add dependencies
|
# Add sources
|
||||||
COPY go.mod /build
|
COPY . /build
|
||||||
COPY go.sum /build
|
|
||||||
COPY package.json /build
|
|
||||||
COPY yarn.lock /build
|
|
||||||
|
|
||||||
# Prepare assets
|
# Prepare assets
|
||||||
RUN yarn install --pure-lockfile --production && \
|
RUN yarn install --pure-lockfile --production && \
|
||||||
|
@ -42,34 +39,30 @@ RUN mkdir -p assets/plugins && \
|
||||||
/build/node_modules/jquery-tags-input/ \
|
/build/node_modules/jquery-tags-input/ \
|
||||||
assets/plugins/
|
assets/plugins/
|
||||||
|
|
||||||
|
# Move custom assets
|
||||||
|
RUN cp -r /build/custom/ assets/
|
||||||
|
|
||||||
# Get go modules and build tool
|
# Get go modules and build tool
|
||||||
RUN go mod download && \
|
RUN go mod download && \
|
||||||
go get github.com/GeertJohan/go.rice/rice
|
go get github.com/GeertJohan/go.rice/rice
|
||||||
|
|
||||||
# Add sources
|
|
||||||
COPY . /build
|
|
||||||
|
|
||||||
# Move custom assets
|
|
||||||
RUN cp -r /build/custom/ assets/
|
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
RUN rice embed-go && \
|
RUN rice embed-go && \
|
||||||
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -o wg-ui .
|
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -o wg-ui .
|
||||||
|
|
||||||
# Release stage
|
# Release stage
|
||||||
FROM alpine:3.11
|
FROM ubuntu:22.04
|
||||||
|
ENV TZ=Europe/Minsk
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
RUN addgroup -S wgui && \
|
RUN apt-get update && apt upgrade -y && apt-get install -y wireguard wireguard-tools iptables iproute2
|
||||||
adduser -S -D -G wgui wgui
|
|
||||||
|
|
||||||
RUN apk --no-cache add ca-certificates
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN mkdir -p db
|
RUN mkdir -p db
|
||||||
|
|
||||||
# Copy binary files
|
# Copy binary files
|
||||||
COPY --from=builder --chown=wgui:wgui /build/wg-ui /app
|
COPY --from=builder /build/wg-ui /app
|
||||||
|
|
||||||
RUN chmod +x wg-ui
|
RUN chmod +x wg-ui
|
||||||
|
|
||||||
|
|
75
README.md
75
README.md
|
@ -9,6 +9,9 @@ A web user interface to manage your WireGuard setup.
|
||||||
- Authentication
|
- Authentication
|
||||||
- Manage extra client's information (name, email, etc)
|
- Manage extra client's information (name, email, etc)
|
||||||
- Retrieve configs using QR code / file
|
- Retrieve configs using QR code / file
|
||||||
|
- start wireguard interface / rules
|
||||||
|
- stop wireguard interface / rules
|
||||||
|
- restart wireguard interface / rules
|
||||||
|
|
||||||
## Run WireGuard-UI
|
## Run WireGuard-UI
|
||||||
|
|
||||||
|
@ -32,8 +35,8 @@ docker-compose up
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
|
|
||||||
- There is a Status option that needs docker to be able to access the network of the host in order to read the
|
- There is a Status option that needs docker to be able to access the network of the host in order to read the
|
||||||
wireguard interface stats. See the `cap_add` and `network_mode` options on the docker-compose.yaml
|
wireguard interface stats. See the `cap_add` and `network_mode` options on the docker-compose.yaml
|
||||||
- Because the `network_mode` is set to `host`, we don't need to specify the exposed ports. The app will listen on port `5000` by default.
|
- Because the `network_mode` is set to `host`, we don't need to specify the exposed ports. The app will listen on port `5000` by default.
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,72 +103,6 @@ EMAIL_FROM_ADDRESS: the sender's email address
|
||||||
EMAIL_FROM_NAME: the sender's name
|
EMAIL_FROM_NAME: the sender's name
|
||||||
```
|
```
|
||||||
|
|
||||||
## Auto restart WireGuard daemon
|
|
||||||
WireGuard-UI only takes care of configuration generation. You can use systemd to watch for the changes and restart the service. Following is an example:
|
|
||||||
|
|
||||||
### systemd
|
|
||||||
|
|
||||||
Create /etc/systemd/system/wgui.service
|
|
||||||
|
|
||||||
```
|
|
||||||
[Unit]
|
|
||||||
Description=Restart WireGuard
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/bin/systemctl restart wg-quick@wg0.service
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
RequiredBy=wgui.path
|
|
||||||
```
|
|
||||||
|
|
||||||
Create /etc/systemd/system/wgui.path
|
|
||||||
|
|
||||||
```
|
|
||||||
[Unit]
|
|
||||||
Description=Watch /etc/wireguard/wg0.conf for changes
|
|
||||||
|
|
||||||
[Path]
|
|
||||||
PathModified=/etc/wireguard/wg0.conf
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply it
|
|
||||||
|
|
||||||
```
|
|
||||||
systemctl enable wgui.{path,service}
|
|
||||||
systemctl start wgui.{path,service}
|
|
||||||
```
|
|
||||||
|
|
||||||
### openrc
|
|
||||||
|
|
||||||
Create and `chmod +x` /usr/local/bin/wgui
|
|
||||||
```
|
|
||||||
#!/bin/sh
|
|
||||||
wg-quick down wg0
|
|
||||||
wg-quick up wg0
|
|
||||||
```
|
|
||||||
|
|
||||||
Create and `chmod +x` /etc/init.d/wgui
|
|
||||||
```
|
|
||||||
#!/sbin/openrc-run
|
|
||||||
|
|
||||||
command=/sbin/inotifyd
|
|
||||||
command_args="/usr/local/bin/wgui /etc/wireguard/wg0.conf:w"
|
|
||||||
pidfile=/run/${RC_SVCNAME}.pid
|
|
||||||
command_background=yes
|
|
||||||
```
|
|
||||||
|
|
||||||
Apply it
|
|
||||||
|
|
||||||
```
|
|
||||||
rc-service wgui start
|
|
||||||
rc-update add wgui default
|
|
||||||
```
|
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
### Build docker image
|
### Build docker image
|
||||||
|
@ -208,4 +145,4 @@ MIT. See [LICENSE](https://github.com/ngoduykhanh/wireguard-ui/blob/master/LICEN
|
||||||
## Support
|
## Support
|
||||||
If you like the project and want to support it, you can *buy me a coffee* ☕
|
If you like the project and want to support it, you can *buy me a coffee* ☕
|
||||||
|
|
||||||
<a href="https://www.buymeacoffee.com/khanhngo" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
|
<a href="https://www.buymeacoffee.com/khanhngo" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
|
|
@ -686,6 +686,82 @@ func SuggestIPAllocation(db store.IStore) echo.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart Wireguard Server handler to stop Wireguard server
|
||||||
|
func RestartServer(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
|
||||||
|
settings, err := db.GetGlobalSettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot get global settings: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get global settings"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Server
|
||||||
|
err = util.StopWireGuardServer(settings)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot stop server: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||||
|
false, fmt.Sprintf("Cannot stop server: %v", err),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Server
|
||||||
|
err = util.StartWireGuardServer(settings)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot start server: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||||
|
false, fmt.Sprintf("Cannot start server: %v", err),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Restarted Wireguard Server successfully"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Wireguard Server handler to stop Wireguard server
|
||||||
|
func StopServer(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
|
||||||
|
settings, err := db.GetGlobalSettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot get global settings: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get global settings"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Server
|
||||||
|
err = util.StopWireGuardServer(settings)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot stop server: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||||
|
false, fmt.Sprintf("Cannot stop server: %v", err),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Stopped Wireguard Server successfully"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Wireguard Server handler to start Wireguard server
|
||||||
|
func StartServer(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
|
||||||
|
settings, err := db.GetGlobalSettings()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot get global settings: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get global settings"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start Server
|
||||||
|
err = util.StartWireGuardServer(settings)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Cannot start server: ", err)
|
||||||
|
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{
|
||||||
|
false, fmt.Sprintf("Cannot start server: %v", err),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Started Wireguard Server successfully"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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, tmplBox *rice.Box) echo.HandlerFunc {
|
func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
|
|
6
main.go
6
main.go
|
@ -17,7 +17,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// command-line banner information
|
// command-line banner information
|
||||||
appVersion = "development"
|
appVersion = "development-2"
|
||||||
gitCommit = "N/A"
|
gitCommit = "N/A"
|
||||||
gitRef = "N/A"
|
gitRef = "N/A"
|
||||||
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
|
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
|
||||||
|
@ -97,6 +97,7 @@ func init() {
|
||||||
//fmt.Println("Session secret\t:", util.SessionSecret)
|
//fmt.Println("Session secret\t:", util.SessionSecret)
|
||||||
fmt.Println("Custom wg.conf\t:", util.WgConfTemplate)
|
fmt.Println("Custom wg.conf\t:", util.WgConfTemplate)
|
||||||
fmt.Println("Base path\t:", util.BasePath + "/")
|
fmt.Println("Base path\t:", util.BasePath + "/")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -154,6 +155,9 @@ func main() {
|
||||||
app.GET(util.BasePath + "/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession)
|
app.GET(util.BasePath + "/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession)
|
||||||
app.GET(util.BasePath + "/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession)
|
app.GET(util.BasePath + "/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession)
|
||||||
app.GET(util.BasePath + "/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession)
|
app.GET(util.BasePath + "/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession)
|
||||||
|
app.GET(util.BasePath + "/api/start-wg", handler.StartServer(db, tmplBox), handler.ValidSession)
|
||||||
|
app.GET(util.BasePath + "/api/stop-wg", handler.StopServer(db, tmplBox), handler.ValidSession)
|
||||||
|
app.GET(util.BasePath + "/api/restart-wg", handler.RestartServer(db, tmplBox), handler.ValidSession)
|
||||||
app.GET(util.BasePath + "/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession)
|
app.GET(util.BasePath + "/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession)
|
||||||
app.POST(util.BasePath + "/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession)
|
app.POST(util.BasePath + "/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession)
|
||||||
app.DELETE(util.BasePath + "/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession)
|
app.DELETE(util.BasePath + "/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession)
|
||||||
|
|
|
@ -64,6 +64,12 @@
|
||||||
<button style="margin-left: 0.5em;" type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
|
<button style="margin-left: 0.5em;" type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
|
||||||
data-target="#modal_apply_config"><i class="nav-icon fas fa-check"></i> Apply
|
data-target="#modal_apply_config"><i class="nav-icon fas fa-check"></i> Apply
|
||||||
Config</button>
|
Config</button>
|
||||||
|
<button id="start-wg" style="margin-left: 0.5em;" type="button"
|
||||||
|
class="btn btn-outline-success btn-sm"><i class="nav-icon fa fa-play"></i> Start</button>
|
||||||
|
<button id="stop-wg" style="margin-left: 0.5em;" type="button"
|
||||||
|
class="btn btn-outline-danger btn-sm"><i class="nav-icon fa fa-stop"></i> Stop</button>
|
||||||
|
<button id="restart-wg" style="margin-left: 0.5em;" type="button"
|
||||||
|
class="btn btn-outline-success btn-sm"><i class="nav-icon fa fa-retweet"></i> Restart</button>
|
||||||
{{if .baseData.CurrentUser}}
|
{{if .baseData.CurrentUser}}
|
||||||
<button onclick="location.href='{{.basePath}}/logout';" style="margin-left: 0.5em;" type="button"
|
<button onclick="location.href='{{.basePath}}/logout';" style="margin-left: 0.5em;" type="button"
|
||||||
class="btn btn-outline-danger btn-sm"><i class="nav-icon fas fa-sign-out-alt"></i> Logout</button>
|
class="btn btn-outline-danger btn-sm"><i class="nav-icon fas fa-sign-out-alt"></i> Logout</button>
|
||||||
|
@ -246,7 +252,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>Do you want to write config file and restart WireGuard server?</p>
|
<p>Do you want to write config file?</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer justify-content-between">
|
<div class="modal-footer justify-content-between">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
@ -489,6 +495,66 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// restart wireguard button event
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#restart-wg").click(function () {
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
method: 'GET',
|
||||||
|
url: '{{.basePath}}/api/restart-wg',
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: "application/json",
|
||||||
|
success: function(data) {
|
||||||
|
toastr.success('Wireguard restart successfully');
|
||||||
|
},
|
||||||
|
error: function(jqXHR, exception) {
|
||||||
|
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||||
|
toastr.error(responseJson['message']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// stop wireguard button event
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#stop-wg").click(function () {
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
method: 'GET',
|
||||||
|
url: '{{.basePath}}/api/stop-wg',
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: "application/json",
|
||||||
|
success: function(data) {
|
||||||
|
toastr.success('Wireguard stopped successfully');
|
||||||
|
},
|
||||||
|
error: function(jqXHR, exception) {
|
||||||
|
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||||
|
toastr.error(responseJson['message']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// start wireguard button event
|
||||||
|
$(document).ready(function () {
|
||||||
|
$("#start-wg").click(function () {
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
method: 'GET',
|
||||||
|
url: '{{.basePath}}/api/start-wg',
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: "application/json",
|
||||||
|
success: function(data) {
|
||||||
|
toastr.success('Wireguard started successfully');
|
||||||
|
},
|
||||||
|
error: function(jqXHR, exception) {
|
||||||
|
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||||
|
toastr.error(responseJson['message']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// apply_config_confirm button event
|
// apply_config_confirm button event
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$("#apply_config_confirm").click(function () {
|
$("#apply_config_confirm").click(function () {
|
||||||
|
|
49
util/util.go
49
util/util.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -375,6 +376,52 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopWireguard Server to stop Wireguard server with config. e.g. wg0.conf
|
||||||
|
func StopWireGuardServer(globalSettings model.GlobalSetting) error {
|
||||||
|
|
||||||
|
app := "wg-quick"
|
||||||
|
|
||||||
|
arg0 := "down"
|
||||||
|
arg1 := globalSettings.ConfigFilePath
|
||||||
|
|
||||||
|
|
||||||
|
cmd := exec.Command(app, arg0, arg1)
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the output
|
||||||
|
fmt.Println(string(stdout))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartWireguard Server to start Wireguard server with config. e.g. wg0.conf
|
||||||
|
func StartWireGuardServer(globalSettings model.GlobalSetting) error {
|
||||||
|
|
||||||
|
app := "wg-quick"
|
||||||
|
|
||||||
|
arg0 := "up"
|
||||||
|
arg1 := globalSettings.ConfigFilePath
|
||||||
|
|
||||||
|
|
||||||
|
cmd := exec.Command(app, arg0, arg1)
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the output
|
||||||
|
fmt.Println(string(stdout))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
|
// WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
|
||||||
func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, globalSettings model.GlobalSetting) error {
|
func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, globalSettings model.GlobalSetting) error {
|
||||||
var tmplWireguardConf string
|
var tmplWireguardConf string
|
||||||
|
@ -456,4 +503,4 @@ func LookupEnvOrStrings(key string, defaultVal []string) []string {
|
||||||
return strings.Split(val, ",")
|
return strings.Split(val, ",")
|
||||||
}
|
}
|
||||||
return defaultVal
|
return defaultVal
|
||||||
}
|
}
|
Loading…
Reference in a new issue