commit
2daadf30ae
14 changed files with 136 additions and 62 deletions
6
.github/workflows/publish-latest.yaml
vendored
6
.github/workflows/publish-latest.yaml
vendored
|
@ -1,8 +1,8 @@
|
|||
name: Build and publish to Docker Hub (releases only)
|
||||
on:
|
||||
name: Build and publish latest tag to Docker Hub (releases only)
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build latest images for relase
|
||||
|
|
4
.github/workflows/publish-tag.yaml
vendored
4
.github/workflows/publish-tag.yaml
vendored
|
@ -1,9 +1,9 @@
|
|||
name: Build and publish to Docker Hub (tags only)
|
||||
name: Build and publish tags to Docker Hub (tags only)
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build images for tag
|
||||
|
|
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
@ -1,3 +1,4 @@
|
|||
name: Build and publish binaries (releases only)
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
@ -10,9 +11,8 @@ jobs:
|
|||
CGO_ENABLED: 1
|
||||
strategy:
|
||||
matrix:
|
||||
# build and publish in parallel: linux/386, linux/amd64, windows/386, windows/amd64, darwin/386, darwin/amd64
|
||||
goos: [linux]
|
||||
goarch: ["386", amd64]
|
||||
goarch: ["386", "amd64"]
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
@ -25,4 +25,4 @@ jobs:
|
|||
ldflags: '-linkmode external -extldflags "-static" -s -w'
|
||||
pre_command: bash ./install-deps.sh
|
||||
binary_name: "ovpn-admin"
|
||||
asset_name: ovpn-admin-${{ matrix.goos }}-${{ matrix.goarch }}.
|
||||
asset_name: ovpn-admin-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||
|
|
28
.github/workflows/release_arm.yaml
vendored
Normal file
28
.github/workflows/release_arm.yaml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
name: Build and publish arm binaries (releases only)
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
releases-matrix:
|
||||
name: Release Go Binary
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CGO_ENABLED: 1
|
||||
strategy:
|
||||
matrix:
|
||||
goos: [linux]
|
||||
goarch: ["arm", "arm64"]
|
||||
steps:
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: build binaries
|
||||
uses: wangyoucao577/go-release-action@v1.20
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
goos: ${{ matrix.goos }}
|
||||
goarch: ${{ matrix.goarch }}
|
||||
build_command: bash ./build_arm.sh
|
||||
pre_command: bash ./install-deps_arm.sh
|
||||
binary_name: "ovpn-admin"
|
||||
asset_name: ovpn-admin-${{ matrix.goos }}-${{ matrix.goarch }}
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -4,10 +4,10 @@ easyrsa_slave
|
|||
ccd
|
||||
ccd_master
|
||||
ccd_slave
|
||||
openvpn-web-ui
|
||||
openvpn-ui
|
||||
openvpn-admin
|
||||
ovpn-admin
|
||||
openvpn-web-ui*
|
||||
openvpn-ui*
|
||||
openvpn-admin*
|
||||
ovpn-admin*
|
||||
frontend/node_modules
|
||||
|
||||
main-packr.go
|
||||
|
|
|
@ -13,5 +13,5 @@ WORKDIR /app
|
|||
COPY --from=backend-builder /app/ovpn-admin /app
|
||||
RUN apk add --update bash easy-rsa && \
|
||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.3-rc.1/openvpn-user-linux-amd64.tar.gz -O - | tar xz -C /usr/local/bin && \
|
||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.3/openvpn-user-linux-amd64.tar.gz -O - | tar xz -C /usr/local/bin && \
|
||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
FROM alpine:3.13
|
||||
RUN apk add --update bash openvpn easy-rsa && \
|
||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.3-rc.1/openvpn-user-linux-amd64.tar.gz -O - | tar xz -C /usr/local/bin && \
|
||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.3/openvpn-user-linux-amd64.tar.gz -O - | tar xz -C /usr/local/bin && \
|
||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||
COPY setup/ /etc/openvpn/setup
|
||||
RUN chmod +x /etc/openvpn/setup/configure.sh
|
||||
|
|
24
README.md
24
README.md
|
@ -63,8 +63,13 @@ cd ovpn-admin
|
|||
|
||||
### 3. Prebuilt binary (WIP)
|
||||
|
||||
|
||||
You can also download and use prebuilt binaries from the [releases](https://github.com/flant/ovpn-admin/releases) page — just choose a relevant tar.gz file.
|
||||
|
||||
|
||||
###
|
||||
If you want to use password auth (`--auth` flag) you have to install [openvpn-user](https://github.com/pashcovich/openvpn-user/releases) - just make it available throw PATH variable and don`t forget about execution rights on the binary
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
|
@ -83,32 +88,31 @@ Flags:
|
|||
--master.sync-frequency=600 master host data sync frequency in seconds.
|
||||
--master.sync-token=TOKEN master host data sync security token
|
||||
--ovpn.network="172.16.100.0/24"
|
||||
network for openvpn server
|
||||
NETWORK/MASK_PREFIX for openvpn server
|
||||
--ovpn.server=HOST:PORT:PROTOCOL ...
|
||||
comma separated addresses for openvpn servers
|
||||
--ovpn.server.behindLB ovpn behind cloud loadbalancer
|
||||
HOST:PORT:PROTOCOL for openvpn server. multiple values
|
||||
--ovpn.server.behindLB ovpn behind k8s loadbalancer
|
||||
--ovpn.service="openvpn-external"
|
||||
ovpn behind cloud loadbalancer k8s service name
|
||||
|
||||
ovpn behind k8s service with type load balancer name
|
||||
--mgmt=main=127.0.0.1:8989 ...
|
||||
comma separated (alias=address) for openvpn servers mgmt interfaces
|
||||
ALIAS=HOST:PORT for openvpn server mgmt interface. multiple values
|
||||
--metrics.path="/metrics" URL path for surfacing collected metrics
|
||||
--easyrsa.path="./easyrsa/" path to easyrsa dir
|
||||
--easyrsa.index-path="./easyrsa/pki/index.txt"
|
||||
path to easyrsa index file.
|
||||
--ccd Enable client-config-dir.
|
||||
--ccd.path="./ccd" path to client-config-dir
|
||||
--templates.clientconfig-path=""
|
||||
path to custom client.config.tpl file
|
||||
--templates.ccd-path="" path to custom ccd.tpl file
|
||||
--templates.clientconfig-path=""
|
||||
path to custom client.conf.tpl
|
||||
--templates.ccd-path="" path to custom ccd.tpl
|
||||
--auth.password Enable additional password authorization.
|
||||
--auth.db="./easyrsa/pki/users.db"
|
||||
Database path fort password authorization.
|
||||
--debug Enable debug mode.
|
||||
--verbose Enable verbose mode.
|
||||
--version Show application version.
|
||||
|
||||
```
|
||||
Also you can configure ovpn-admin throw environment variables
|
||||
|
||||
## Further information
|
||||
|
||||
|
|
2
build.sh
2
build.sh
|
@ -2,8 +2,6 @@
|
|||
|
||||
PATH=$PATH:~/go/bin
|
||||
|
||||
#go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
|
||||
cd frontend && npm install && npm run build && cd ..
|
||||
|
||||
packr2
|
||||
|
|
18
build_arm.sh
Executable file
18
build_arm.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
PATH=$PATH:~/go/bin
|
||||
|
||||
cd frontend && npm install && npm run build && cd ..
|
||||
|
||||
packr2
|
||||
|
||||
if [[ "$GOOS" == "linux" ]]; then
|
||||
if [[ "$GOARCH" == "arm" ]]; then
|
||||
CC=arm-linux-gnueabi-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm go build -ldflags "-linkmode external -extldflags -static -s -w" $@
|
||||
fi
|
||||
if [[ "$GOARCH" == "arm64" ]]; then
|
||||
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "-linkmode external -extldflags -static -s -w" $@
|
||||
fi
|
||||
fi
|
||||
|
||||
packr2 clean
|
|
@ -7,6 +7,9 @@ services:
|
|||
dockerfile: Dockerfile.openvpn
|
||||
image: openvpn:local
|
||||
command: /etc/openvpn/setup/configure.sh
|
||||
environment:
|
||||
OVPN_SERVER_NET: "192.168.100.0"
|
||||
OVPN_SERVER_MASK: "255.255.255.0"
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
|
@ -19,7 +22,14 @@ services:
|
|||
build:
|
||||
context: .
|
||||
image: ovpn-admin:local
|
||||
command: /app/ovpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --easyrsa.path="/mnt/easyrsa" --easyrsa.index-path="/mnt/easyrsa/pki/index.txt" --ovpn.server="127.0.0.1:7777:tcp"
|
||||
command: /app/ovpn-admin
|
||||
environment:
|
||||
OVPN_DEBUG: "True"
|
||||
OVPN_VERBOSE: "True"
|
||||
OVPN_NETWORK: "192.168.100.0/24"
|
||||
EASYRSA_PATH: "/mnt/easyrsa"
|
||||
OVPN_SERVER: "127.0.0.1:7777:tcp"
|
||||
OVPN_INDEX_PATH: "/mnt/easyrsa/pki/index.txt"
|
||||
network_mode: service:openvpn
|
||||
volumes:
|
||||
- ./easyrsa_master:/mnt/easyrsa
|
||||
|
|
13
install-deps-arm.sh
Executable file
13
install-deps-arm.sh
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
apt-get update
|
||||
apt-get install -y curl
|
||||
apt-get install -y libc6 libc6-dev gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu
|
||||
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | bash -
|
||||
apt-get install -y nodejs
|
||||
|
||||
PATH=$PATH:~/go/bin
|
||||
|
||||
go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
apt-get update
|
||||
apt-get install -y curl
|
||||
apt-get install -y gcc-multilib libc6 libc6-dev libc6-dev-i386
|
||||
apt-get install -y libc6 libc6-dev libc6-dev-i386
|
||||
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | bash -
|
||||
apt-get install -y nodejs
|
||||
|
@ -12,6 +11,3 @@ PATH=$PATH:~/go/bin
|
|||
|
||||
go get -u github.com/gobuffalo/packr/v2/packr2
|
||||
|
||||
cd frontend && npm install && npm run build && cd ..
|
||||
|
||||
packr2
|
||||
|
|
67
main.go
67
main.go
|
@ -38,42 +38,41 @@ const (
|
|||
indexTxtDateLayout = "060102150405Z"
|
||||
stringDateFormat = "2006-01-02 15:04:05"
|
||||
ovpnStatusDateLayout = "2006-01-02 15:04:05"
|
||||
|
||||
kubeTokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
||||
kubeNamespaceFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
|
||||
)
|
||||
|
||||
var (
|
||||
listenHost = kingpin.Flag("listen.host","host for ovpn-admin").Default("0.0.0.0").String()
|
||||
listenPort = kingpin.Flag("listen.port","port for ovpn-admin").Default("8080").String()
|
||||
serverRole = kingpin.Flag("role","server role master or slave").Default("master").HintOptions("master", "slave").String()
|
||||
masterHost = kingpin.Flag("master.host","url for master server").Default("http://127.0.0.1").String()
|
||||
masterBasicAuthUser = kingpin.Flag("master.basic-auth.user","user for basic auth on master server url").Default("").String()
|
||||
masterBasicAuthPassword = kingpin.Flag("master.basic-auth.password","password for basic auth on master server url").Default("").String()
|
||||
masterSyncFrequency = kingpin.Flag("master.sync-frequency", "master host data sync frequency in seconds.").Default("600").Int()
|
||||
masterSyncToken = kingpin.Flag("master.sync-token", "master host data sync security token").Default("VerySecureToken").PlaceHolder("TOKEN").String()
|
||||
openvpnNetwork = kingpin.Flag("ovpn.network","network for openvpn server").Default("172.16.100.0/24").String()
|
||||
openvpnServer = kingpin.Flag("ovpn.server","comma separated addresses for openvpn servers").Default("127.0.0.1:7777:tcp").PlaceHolder("HOST:PORT:PROTOCOL").Strings()
|
||||
openvpnServerBehindLB = kingpin.Flag("ovpn.server.behindLB","ovpn behind cloud loadbalancer").Default("false").Bool()
|
||||
openvpnServiceName = kingpin.Flag("ovpn.service","ovpn behind cloud loadbalancer k8s service name").Default("openvpn-external").String()
|
||||
mgmtAddress = kingpin.Flag("mgmt","comma separated (alias=address) for openvpn servers mgmt interfaces").Default("main=127.0.0.1:8989").Strings()
|
||||
metricsPath = kingpin.Flag("metrics.path", "URL path for surfacing collected metrics").Default("/metrics").String()
|
||||
easyrsaDirPath = kingpin.Flag("easyrsa.path", "path to easyrsa dir").Default("./easyrsa/").String()
|
||||
indexTxtPath = kingpin.Flag("easyrsa.index-path", "path to easyrsa index file.").Default("./easyrsa/pki/index.txt").String()
|
||||
ccdEnabled = kingpin.Flag("ccd", "Enable client-config-dir.").Default("false").Bool()
|
||||
ccdDir = kingpin.Flag("ccd.path", "path to client-config-dir").Default("./ccd").String()
|
||||
clientConfigTemplatePath = kingpin.Flag("templates.clientconfig-path", "path to custom client.conf.tpl").Default("").String()
|
||||
ccdTemplatePath = kingpin.Flag("templates.ccd-path", "path to custom ccd.tpl").Default("").String()
|
||||
authByPassword = kingpin.Flag("auth.password", "Enable additional password authorization.").Default("false").Bool()
|
||||
authDatabase = kingpin.Flag("auth.db", "Database path fort password authorization.").Default("./easyrsa/pki/users.db").String()
|
||||
debug = kingpin.Flag("debug", "Enable debug mode.").Default("false").Bool()
|
||||
verbose = kingpin.Flag("verbose", "Enable verbose mode.").Default("false").Bool()
|
||||
listenHost = kingpin.Flag("listen.host","host for ovpn-admin").Default("0.0.0.0").Envar("OVPN_LISTEN_HOST").String()
|
||||
listenPort = kingpin.Flag("listen.port","port for ovpn-admin").Default("8080").Envar("OVPN_LISTEN_PROT").String()
|
||||
serverRole = kingpin.Flag("role","server role master or slave").Default("master").Envar("OVPN_ROLE").HintOptions("master", "slave").String()
|
||||
masterHost = kingpin.Flag("master.host","url for master server").Default("http://127.0.0.1").Envar("OVPN_MASTER_HOST").String()
|
||||
masterBasicAuthUser = kingpin.Flag("master.basic-auth.user","user for basic auth on master server url").Default("").Envar("OVPN_MASTER_USER").String()
|
||||
masterBasicAuthPassword = kingpin.Flag("master.basic-auth.password","password for basic auth on master server url").Default("").Envar("OVPN_MASTER_PASSWORD").String()
|
||||
masterSyncFrequency = kingpin.Flag("master.sync-frequency", "master host data sync frequency in seconds.").Default("600").Envar("OVPN_MASTER_SYNC_FREQUENCY").Int()
|
||||
masterSyncToken = kingpin.Flag("master.sync-token", "master host data sync security token").Default("VerySecureToken").Envar("OVPN_MASTER_TOKEN").PlaceHolder("TOKEN").String()
|
||||
openvpnNetwork = kingpin.Flag("ovpn.network","NETWORK/MASK_PREFIX for openvpn server").Default("172.16.100.0/24").Envar("OVPN_NETWORK").String()
|
||||
openvpnServer = kingpin.Flag("ovpn.server","HOST:PORT:PROTOCOL for openvpn server. multiple values").Default("127.0.0.1:7777:tcp").Envar("OVPN_SERVER").PlaceHolder("HOST:PORT:PROTOCOL").Strings()
|
||||
openvpnServerBehindLB = kingpin.Flag("ovpn.server.behindLB","ovpn behind k8s loadbalancer").Default("false").Envar("OVPN_LB").Bool()
|
||||
openvpnServiceName = kingpin.Flag("ovpn.service","ovpn behind k8s service with type load balancer name").Default("openvpn-external").Envar("OVPN_LB_SERVICE").String()
|
||||
mgmtAddress = kingpin.Flag("mgmt","ALIAS=HOST:PORT for openvpn server mgmt interface. multiple values").Default("main=127.0.0.1:8989").Envar("OVPN_MGMT").Strings()
|
||||
metricsPath = kingpin.Flag("metrics.path", "URL path for surfacing collected metrics").Default("/metrics").Envar("OVPN_METRICS_PATH").String()
|
||||
easyrsaDirPath = kingpin.Flag("easyrsa.path", "path to easyrsa dir").Default("./easyrsa/").Envar("EASYRSA_PATH").String()
|
||||
indexTxtPath = kingpin.Flag("easyrsa.index-path", "path to easyrsa index file.").Default("./easyrsa/pki/index.txt").Envar("OVPN_INDEX_PATH").String()
|
||||
ccdEnabled = kingpin.Flag("ccd", "Enable client-config-dir.").Default("false").Envar("OVPN_CCD").Bool()
|
||||
ccdDir = kingpin.Flag("ccd.path", "path to client-config-dir").Default("./ccd").Envar("OVPN_CCD_PATH").String()
|
||||
clientConfigTemplatePath = kingpin.Flag("templates.clientconfig-path", "path to custom client.conf.tpl").Default("").Envar("OVPN_TEMPLATES_CCD_PATH").String()
|
||||
ccdTemplatePath = kingpin.Flag("templates.ccd-path", "path to custom ccd.tpl").Default("").Envar("OVPN_TEMPLATES_CCD_PATH").String()
|
||||
authByPassword = kingpin.Flag("auth.password", "Enable additional password authorization.").Default("false").Envar("OVPN_AUTH").Bool()
|
||||
authDatabase = kingpin.Flag("auth.db", "Database path fort password authorization.").Default("./easyrsa/pki/users.db").Envar("OVPN_AUTH_DB_PATH").String()
|
||||
debug = kingpin.Flag("debug", "Enable debug mode.").Default("false").Envar("OVPN_DEBUG").Bool()
|
||||
verbose = kingpin.Flag("verbose", "Enable verbose mode.").Default("false").Envar("OVPN_VERBOSE").Bool()
|
||||
|
||||
certsArchivePath = "/tmp/" + certsArchiveFileName
|
||||
ccdArchivePath = "/tmp/" + ccdArchiveFileName
|
||||
|
||||
version = "1.7.0"
|
||||
|
||||
kubeTokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
||||
kubeNamespaceFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
|
||||
|
||||
version = "1.7.4"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -431,6 +430,14 @@ func main() {
|
|||
go ovpnAdmin.syncWithMaster()
|
||||
}
|
||||
|
||||
if *debug {
|
||||
log.Println("Runnnig in debug mode")
|
||||
}
|
||||
|
||||
if *verbose {
|
||||
log.Println("Runnnig in verbose mode")
|
||||
}
|
||||
|
||||
ovpnAdmin.templates = packr.New("template", "./templates")
|
||||
|
||||
staticBox := packr.New("static", "./frontend/static")
|
||||
|
@ -459,7 +466,7 @@ func main() {
|
|||
fmt.Fprintf(w, "pong")
|
||||
})
|
||||
|
||||
fmt.Println("Bind: http://" + *listenHost + ":" + *listenPort)
|
||||
log.Printf("Bind: http://%s:%s\n", *listenHost, *listenPort)
|
||||
log.Fatal(http.ListenAndServe(*listenHost+":"+*listenPort, nil))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue