Additional password auth; Multiple mgmt interface usgae; Fixes; style changes;
This commit is contained in:
parent
bec0e738d1
commit
3614ab6ba5
14 changed files with 57 additions and 156 deletions
10
Dockerfile
10
Dockerfile
|
@ -1,22 +1,18 @@
|
||||||
FROM golang:1.14.2-alpine3.11 AS backend-builder
|
FROM golang:1.14.2-buster AS backend-builder
|
||||||
COPY . /app
|
COPY . /app
|
||||||
#RUN apk --no-cache add build-base git gcc
|
RUN cd /app && env CGO_ENABLED=./1 GOOS=linux GOARCH=amd64 go build -ldflags='-linkmode external -extldflags "-static" -s -w' -o openvpn-admin
|
||||||
RUN cd /app && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
|
||||||
|
|
||||||
FROM node:14.2-alpine3.11 AS frontend-builder
|
FROM node:14.2-alpine3.11 AS frontend-builder
|
||||||
COPY frontend/ /app
|
COPY frontend/ /app
|
||||||
RUN cd /app && npm install && npm run build
|
RUN cd /app && npm install && npm run build
|
||||||
|
|
||||||
FROM golang:1.14.2-buster AS user-builder
|
|
||||||
RUN git clone https://github.com/pashcovich/openvpn-user /app && cd /app && env CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags='-linkmode external -extldflags "-static" -s -w' -o openvpn-user
|
|
||||||
|
|
||||||
FROM alpine:3.13
|
FROM alpine:3.13
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=backend-builder /app/openvpn-admin /app
|
COPY --from=backend-builder /app/openvpn-admin /app
|
||||||
COPY --from=user-builder /app/openvpn-user /usr/local/bin
|
|
||||||
COPY --from=frontend-builder /app/static /app/static
|
COPY --from=frontend-builder /app/static /app/static
|
||||||
COPY client.conf.tpl /app/client.conf.tpl
|
COPY client.conf.tpl /app/client.conf.tpl
|
||||||
COPY ccd.tpl /app/ccd.tpl
|
COPY ccd.tpl /app/ccd.tpl
|
||||||
RUN apk add --update bash easy-rsa && \
|
RUN apk add --update bash easy-rsa && \
|
||||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
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 && \
|
||||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
FROM golang:1.14.2-buster AS user-builder
|
|
||||||
RUN git clone https://github.com/pashcovich/openvpn-user /app && cd /app && env CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags='-linkmode external -extldflags "-static" -s -w' -o openvpn-user
|
|
||||||
|
|
||||||
FROM alpine:3.13
|
FROM alpine:3.13
|
||||||
COPY --from=user-builder /app/openvpn-user /usr/local/bin
|
|
||||||
RUN apk add --update bash openvpn easy-rsa && \
|
RUN apk add --update bash openvpn easy-rsa && \
|
||||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
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 && \
|
||||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||||
COPY .werffiles /etc/openvpn/setup
|
COPY setup/ /etc/openvpn/setup
|
||||||
RUN chmod +x /etc/openvpn/setup/configure.sh
|
RUN chmod +x /etc/openvpn/setup/configure.sh
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags "-linkmode external -extldflags -static -s -w" -o openvpn-admin
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{- range $server := .Hosts }}
|
{{- range $server := .Hosts }}
|
||||||
remote {{ $server.Host }} {{ $server.Port }} tcp
|
remote {{ $server.Host }} {{ $server.Port }} {{ $server.Protocol }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
verb 4
|
verb 4
|
||||||
|
|
|
@ -22,7 +22,7 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
image: openvpn-admin:local
|
image: openvpn-admin:local
|
||||||
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --master.host="http://172.20.0.1:8080" --role="slave" --ovpn.host="127.0.0.1:7744" --ovpn.host="127.0.0.1:7778" --auth.password
|
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --master.host="http://172.20.0.1:8080" --role="slave" --ovpn.server="127.0.0.1:7744" --ovpn.server="127.0.0.1:7778" --auth.password
|
||||||
environment:
|
environment:
|
||||||
- OPVN_SLAVE=1
|
- OPVN_SLAVE=1
|
||||||
network_mode: service:openvpn
|
network_mode: service:openvpn
|
||||||
|
|
5
frontend/package-lock.json
generated
5
frontend/package-lock.json
generated
|
@ -7838,6 +7838,11 @@
|
||||||
"vue-style-loader": "^4.1.0"
|
"vue-style-loader": "^4.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-notification": {
|
||||||
|
"version": "1.3.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-notification/-/vue-notification-1.3.20.tgz",
|
||||||
|
"integrity": "sha512-vPj67Ah72p8xvtyVE8emfadqVWguOScAjt6OJDEUdcW5hW189NsqvfkOrctxHUUO9UYl9cTbIkzAEcPnHu+zBQ=="
|
||||||
|
},
|
||||||
"vue-style-loader": {
|
"vue-style-loader": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
"vue-clipboard2": "^0.2.1",
|
"vue-clipboard2": "^0.2.1",
|
||||||
"vue-cookies": "^1.7.4",
|
"vue-cookies": "^1.7.4",
|
||||||
"vue-good-table": "^2.21.1"
|
"vue-good-table": "^2.21.1",
|
||||||
|
"vue-notification": "^1.3.20"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
|
|
@ -3,12 +3,14 @@ import axios from 'axios';
|
||||||
import VueCookies from 'vue-cookies'
|
import VueCookies from 'vue-cookies'
|
||||||
import VueClipboard from 'vue-clipboard2'
|
import VueClipboard from 'vue-clipboard2'
|
||||||
import VueGoodTablePlugin from 'vue-good-table'
|
import VueGoodTablePlugin from 'vue-good-table'
|
||||||
|
import Notifications from 'vue-notification'
|
||||||
|
|
||||||
import 'vue-good-table/dist/vue-good-table.css'
|
import 'vue-good-table/dist/vue-good-table.css'
|
||||||
|
|
||||||
Vue.use(VueClipboard)
|
Vue.use(VueClipboard)
|
||||||
Vue.use(VueGoodTablePlugin)
|
Vue.use(VueGoodTablePlugin)
|
||||||
Vue.use(VueCookies)
|
Vue.use(VueCookies)
|
||||||
|
Vue.use(Notifications)
|
||||||
|
|
||||||
var axios_cfg = function(url, data='', type='form') {
|
var axios_cfg = function(url, data='', type='form') {
|
||||||
if (data == '') {
|
if (data == '') {
|
||||||
|
@ -182,6 +184,7 @@ new Vue({
|
||||||
axios.request(axios_cfg('api/user/revoke', data, 'form'))
|
axios.request(axios_cfg('api/user/revoke', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
|
_this.$notify({title: 'User ' + _this.username + ' revoked!', type: 'warn'})
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
_this.$root.$on('u-unrevoke', function () {
|
_this.$root.$on('u-unrevoke', function () {
|
||||||
|
@ -190,6 +193,7 @@ new Vue({
|
||||||
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
|
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
|
_this.$notify({title: 'User ' + _this.username + ' unrevoked!', type: 'success'})
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
_this.$root.$on('u-show-config', function () {
|
_this.$root.$on('u-show-config', function () {
|
||||||
|
@ -289,6 +293,15 @@ new Vue({
|
||||||
_this.rows = response.data;
|
_this.rows = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
staticAddrCheckboxOnChange: function() {
|
||||||
|
var staticAddrInput = document.getElementById('static-address');
|
||||||
|
var staticAddrEnable = document.getElementById('enable-static');
|
||||||
|
|
||||||
|
staticAddrInput.disabled = !staticAddrEnable.checked;
|
||||||
|
staticAddrInput.value == "dynamic" ? staticAddrInput.value = "" : staticAddrInput.value = "dynamic";
|
||||||
|
},
|
||||||
|
|
||||||
getServerRole: function() {
|
getServerRole: function() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
axios.request(axios_cfg('api/server/role'))
|
axios.request(axios_cfg('api/server/role'))
|
||||||
|
@ -318,9 +331,12 @@ new Vue({
|
||||||
_this.u.newUserName = '';
|
_this.u.newUserName = '';
|
||||||
_this.u.newUserPassword = '';
|
_this.u.newUserPassword = '';
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
|
_this.$notify({title: 'New user ' + _this.username + ' created', type: 'success'})
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
_this.u.newUserCreateError = error.response.data;
|
_this.u.newUserCreateError = error.response.data;
|
||||||
|
_this.$notify({title: 'New user ' + _this.username + ' creation failed.', type: 'error'})
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -334,10 +350,12 @@ new Vue({
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.u.ccdApplyStatus = 200;
|
_this.u.ccdApplyStatus = 200;
|
||||||
_this.u.ccdApplyStatusMessage = response.data;
|
_this.u.ccdApplyStatusMessage = response.data;
|
||||||
|
_this.$notify({title: 'Ccd for user ' + _this.username + ' applied', type: 'success'})
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
_this.u.ccdApplyStatus = error.response.status;
|
_this.u.ccdApplyStatus = error.response.status;
|
||||||
_this.u.ccdApplyStatusMessage = error.response.data;
|
_this.u.ccdApplyStatusMessage = error.response.data;
|
||||||
|
_this.$notify({title: 'Ccd for user ' + _this.username + ' apply failed ', type: 'error'})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -354,13 +372,14 @@ new Vue({
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.u.passwordChangeStatus = 200;
|
_this.u.passwordChangeStatus = 200;
|
||||||
_this.u.newPassword = '';
|
_this.u.newPassword = '';
|
||||||
_this.u.passwordChangeMessage = response.data.message;
|
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
_this.u.modalChangePasswordVisible = false;
|
_this.u.modalChangePasswordVisible = false;
|
||||||
|
_this.$notify({title: 'Password for user ' + _this.username + ' changed!', type: 'success'})
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
_this.u.passwordChangeStatus = error.response.status;
|
_this.u.passwordChangeStatus = error.response.status;
|
||||||
_this.u.passwordChangeMessage = error.response.data.message;
|
_this.u.passwordChangeMessage = error.response.data.message;
|
||||||
|
_this.$notify({title: 'Changing password for user ' + _this.username + ' failed!', type: 'error'})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="changeUserPassword(username)">Change password</button>
|
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="changeUserPassword(username)">Change password</button>
|
||||||
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newPassword='';u.modalChangePasswordVisible=false">Close</button>
|
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newPassword='';u.passwordChangeMessage='';u.modalChangePasswordVisible=false">Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -127,10 +127,10 @@
|
||||||
<h5 class="static-address-label ">Static address:</h5>
|
<h5 class="static-address-label ">Static address:</h5>
|
||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<div class="input-group-text">
|
<div class="input-group-text">
|
||||||
<input id="enable-static" type="checkbox" onchange="document.getElementById('staticAddress').disabled=!this.checked;" v-if="serverRole == 'master'" v-bind:checked="!customAddressDisabled">
|
<input id="enable-static" type="checkbox" @change="staticAddrCheckboxOnChange()" v-if="serverRole == 'master'" v-bind:checked="!customAddressDisabled">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input id="staticAddress" type="text" class="form-control" v-model="u.ccd.ClientAddress" placeholder="127.0.0.1" v-bind:disabled="customAddressDisabled">
|
<input id="static-address" type="text" class="form-control" v-model="u.ccd.ClientAddress" placeholder="127.0.0.1" v-bind:disabled="customAddressDisabled">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
@ -147,22 +147,22 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(customRoute, index) in u.ccd.CustomRoutes">
|
<tr v-for="(customRoute, index) in u.ccd.CustomRoutes">
|
||||||
<td>
|
<td>
|
||||||
<div v-if = "serverRole == 'slave'">
|
<div v-if="serverRole == 'slave'">
|
||||||
{{ customRoute.Address }}
|
{{ customRoute.Address }}
|
||||||
</div>
|
</div>
|
||||||
<input v-if = "serverRole == 'master'" v-model = "customRoute.Address">
|
<input v-if="serverRole == 'master'" v-model="customRoute.Address">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div v-if = "serverRole == 'slave'">
|
<div v-if="serverRole == 'slave'">
|
||||||
{{ customRoute.Mask }}
|
{{ customRoute.Mask }}
|
||||||
</div>
|
</div>
|
||||||
<input v-if = "serverRole == 'master'" v-model = "customRoute.Mask">
|
<input v-if="serverRole == 'master'" v-model="customRoute.Mask">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div v-if = "serverRole == 'slave'">
|
<div v-if="serverRole == 'slave'">
|
||||||
{{ customRoute.Description }}
|
{{ customRoute.Description }}
|
||||||
</div>
|
</div>
|
||||||
<input v-if = "serverRole == 'master'" v-model = "customRoute.Description">
|
<input v-if="serverRole == 'master'" v-model="customRoute.Description">
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right" v-if="serverRole == 'master'">
|
<td class="text-right" v-if="serverRole == 'master'">
|
||||||
<button type="button" class="btn btn-danger btn-sm el-square modal-el-margin" v-if="serverRole == 'master'" v-on:click.stop="u.ccd.CustomRoutes.splice(index, 1)">Delete</button>
|
<button type="button" class="btn btn-danger btn-sm el-square modal-el-margin" v-if="serverRole == 'master'" v-on:click.stop="u.ccd.CustomRoutes.splice(index, 1)">Delete</button>
|
||||||
|
@ -193,6 +193,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<notifications position="bottom left" :speed="900" />
|
||||||
</div>
|
</div>
|
||||||
<script src="dist/build.js"></script>
|
<script src="dist/build.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
22
main.go
22
main.go
|
@ -30,10 +30,10 @@ const (
|
||||||
indexTxtDateLayout = "060102150405Z"
|
indexTxtDateLayout = "060102150405Z"
|
||||||
stringDateFormat = "2006-01-02 15:04:05"
|
stringDateFormat = "2006-01-02 15:04:05"
|
||||||
ovpnStatusDateLayout = "Mon Jan 2 15:04:05 2006"
|
ovpnStatusDateLayout = "Mon Jan 2 15:04:05 2006"
|
||||||
|
version = "1.5.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
||||||
listenHost = kingpin.Flag("listen.host","host for openvpn-admin").Default("0.0.0.0").String()
|
listenHost = kingpin.Flag("listen.host","host for openvpn-admin").Default("0.0.0.0").String()
|
||||||
listenPort = kingpin.Flag("listen.port","port for openvpn-admin").Default("8080").String()
|
listenPort = kingpin.Flag("listen.port","port for openvpn-admin").Default("8080").String()
|
||||||
serverRole = kingpin.Flag("role","server role master or slave").Default("master").HintOptions("master", "slave").String()
|
serverRole = kingpin.Flag("role","server role master or slave").Default("master").HintOptions("master", "slave").String()
|
||||||
|
@ -42,10 +42,9 @@ var (
|
||||||
masterBasicAuthPassword = kingpin.Flag("master.basic-auth.password","password 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()
|
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("justasimpleword").PlaceHolder("TOKEN").String()
|
masterSyncToken = kingpin.Flag("master.sync-token", "master host data sync security token").Default("justasimpleword").PlaceHolder("TOKEN").String()
|
||||||
openvpnServer = kingpin.Flag("ovpn.host","host(s) for openvpn server").Default("127.0.0.1:7777").PlaceHolder("HOST:PORT").Strings()
|
openvpnServer = kingpin.Flag("ovpn.server","comma separated addresses for openvpn servers").Default("127.0.0.1:7777").PlaceHolder("HOST:PORT").Strings()
|
||||||
openvpnNetwork = kingpin.Flag("ovpn.network","network for openvpn server").Default("172.16.100.0/24").String()
|
openvpnNetwork = kingpin.Flag("ovpn.network","network for openvpn server").Default("172.16.100.0/24").String()
|
||||||
mgmtAddress = kingpin.Flag("mgmt","comma separated (alias=addresses) for openvpn servers mgmt interfaces").Default("main=127.0.0.1:8989").Strings()
|
mgmtAddress = kingpin.Flag("mgmt","comma separated (alias=address) for openvpn servers mgmt interfaces").Default("main=127.0.0.1:8989").Strings()
|
||||||
//mgmtListenPort = kingpin.Flag("mgmt.port","port for openvpn server mgmt interface").Default("8989").String()
|
|
||||||
metricsPath = kingpin.Flag("metrics.path", "URL path for surfacing collected metrics").Default("/metrics").String()
|
metricsPath = kingpin.Flag("metrics.path", "URL path for surfacing collected metrics").Default("/metrics").String()
|
||||||
easyrsaDirPath = kingpin.Flag("easyrsa.path", "path to easyrsa dir").Default("/mnt/easyrsa").String()
|
easyrsaDirPath = kingpin.Flag("easyrsa.path", "path to easyrsa dir").Default("/mnt/easyrsa").String()
|
||||||
indexTxtPath = kingpin.Flag("easyrsa.index-path", "path to easyrsa index file.").Default("/mnt/easyrsa/pki/index.txt").String()
|
indexTxtPath = kingpin.Flag("easyrsa.index-path", "path to easyrsa index file.").Default("/mnt/easyrsa/pki/index.txt").String()
|
||||||
|
@ -152,6 +151,7 @@ type OpenvpnAdmin struct {
|
||||||
type OpenvpnServer struct {
|
type OpenvpnServer struct {
|
||||||
Host string
|
Host string
|
||||||
Port string
|
Port string
|
||||||
|
Protocol string
|
||||||
}
|
}
|
||||||
|
|
||||||
type openvpnClientConfig struct {
|
type openvpnClientConfig struct {
|
||||||
|
@ -366,7 +366,9 @@ func (oAdmin *OpenvpnAdmin) downloadCcdHandler(w http.ResponseWriter, r *http.Re
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
kingpin.Parse()
|
kingpin.Version(version)
|
||||||
|
kingpin.Parse()
|
||||||
|
|
||||||
|
|
||||||
ovpnAdmin := new(OpenvpnAdmin)
|
ovpnAdmin := new(OpenvpnAdmin)
|
||||||
ovpnAdmin.lastSyncTime = "unknown"
|
ovpnAdmin.lastSyncTime = "unknown"
|
||||||
|
@ -506,8 +508,8 @@ func (oAdmin *OpenvpnAdmin) renderClientConfig(username string) string {
|
||||||
var hosts []OpenvpnServer
|
var hosts []OpenvpnServer
|
||||||
|
|
||||||
for _, server := range *openvpnServer {
|
for _, server := range *openvpnServer {
|
||||||
parts := strings.SplitN(server, ":",2)
|
parts := strings.SplitN(server, ":",3)
|
||||||
hosts = append(hosts, OpenvpnServer{Host: parts[0], Port: parts[1]})
|
hosts = append(hosts, OpenvpnServer{Host: parts[0], Port: parts[1], Protocol: parts[2]})
|
||||||
}
|
}
|
||||||
|
|
||||||
conf := openvpnClientConfig{}
|
conf := openvpnClientConfig{}
|
||||||
|
@ -947,7 +949,7 @@ func (oAdmin *OpenvpnAdmin) mgmtConnectedUsersParser(text, serverName string) []
|
||||||
func (oAdmin *OpenvpnAdmin) mgmtKillUserConnection(username, serverName string) {
|
func (oAdmin *OpenvpnAdmin) mgmtKillUserConnection(username, serverName string) {
|
||||||
conn, err := net.Dial("tcp", oAdmin.mgmtInterfaces[serverName])
|
conn, err := net.Dial("tcp", oAdmin.mgmtInterfaces[serverName])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("ERROR: openvpn mgmt interface is not reachable")
|
log.Printf("WARNING: openvpn mgmt interface for %s is not reachable by addr %s\n", serverName, oAdmin.mgmtInterfaces[serverName])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
oAdmin.mgmtRead(conn) // read welcome message
|
oAdmin.mgmtRead(conn) // read welcome message
|
||||||
|
@ -962,8 +964,8 @@ func (oAdmin *OpenvpnAdmin) mgmtGetActiveClients() []clientStatus {
|
||||||
for srv, addr := range oAdmin.mgmtInterfaces {
|
for srv, addr := range oAdmin.mgmtInterfaces {
|
||||||
conn, err := net.Dial("tcp", addr)
|
conn, err := net.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ERROR: openvpn mgmt interface for %s is not reachable by addr %s\n", srv, addr)
|
log.Printf("WARNING: openvpn mgmt interface for %s is not reachable by addr %s\n", srv, addr)
|
||||||
//return []clientStatus{}
|
break
|
||||||
}
|
}
|
||||||
oAdmin.mgmtRead(conn) // read welcome message
|
oAdmin.mgmtRead(conn) // read welcome message
|
||||||
conn.Write([]byte("status\n"))
|
conn.Write([]byte("status\n"))
|
||||||
|
|
120
werf.yaml
120
werf.yaml
|
@ -1,120 +0,0 @@
|
||||||
project: openvpn-admin
|
|
||||||
configVersion: 1
|
|
||||||
deploy:
|
|
||||||
helmRelease: "[[ project ]]-[[ env ]]"
|
|
||||||
namespace: "[[ project ]]-[[ env ]]"
|
|
||||||
|
|
||||||
---
|
|
||||||
artifact: backend-builder
|
|
||||||
from: golang:1.14.2-alpine3.11
|
|
||||||
git:
|
|
||||||
- add: /
|
|
||||||
to: /app
|
|
||||||
stageDependencies:
|
|
||||||
install:
|
|
||||||
- "*.go"
|
|
||||||
excludePaths:
|
|
||||||
- .helm
|
|
||||||
- .werf
|
|
||||||
- frontend
|
|
||||||
- werf.yaml
|
|
||||||
- Dockerfile
|
|
||||||
ansible:
|
|
||||||
install:
|
|
||||||
- name: Install packages
|
|
||||||
apk:
|
|
||||||
name:
|
|
||||||
- build-base
|
|
||||||
- gcc
|
|
||||||
- name: Build backend
|
|
||||||
command: go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
|
||||||
environment:
|
|
||||||
CGO_ENABLED: 0
|
|
||||||
GOOS: linux
|
|
||||||
GOARCH: amd64
|
|
||||||
args:
|
|
||||||
chdir: /app
|
|
||||||
|
|
||||||
---
|
|
||||||
artifact: frontend-builder
|
|
||||||
from: node:14.2-alpine3.11
|
|
||||||
git:
|
|
||||||
- add: /frontend
|
|
||||||
to: /app
|
|
||||||
stageDependencies:
|
|
||||||
install:
|
|
||||||
- "**/*"
|
|
||||||
excludePaths:
|
|
||||||
- Dockerfile
|
|
||||||
- build.sh
|
|
||||||
- werf.yaml
|
|
||||||
ansible:
|
|
||||||
setup:
|
|
||||||
- name: install deps
|
|
||||||
command: npm install
|
|
||||||
args:
|
|
||||||
chdir: /app
|
|
||||||
- name: Build app
|
|
||||||
command: npm run build
|
|
||||||
args:
|
|
||||||
chdir: /app
|
|
||||||
|
|
||||||
---
|
|
||||||
image: openvpn-admin
|
|
||||||
from: alpine:3.11
|
|
||||||
import:
|
|
||||||
- artifact: backend-builder
|
|
||||||
add: /app/openvpn-admin
|
|
||||||
to: /usr/bin/openvpn-admin
|
|
||||||
before: setup
|
|
||||||
- artifact: frontend-builder
|
|
||||||
add: /app/static
|
|
||||||
to: /app/static
|
|
||||||
before: setup
|
|
||||||
git:
|
|
||||||
- add: /client.conf.tpl
|
|
||||||
to: /app/client.conf.tpl
|
|
||||||
stageDependencies:
|
|
||||||
setup:
|
|
||||||
- "*"
|
|
||||||
- add: /ccd.tpl
|
|
||||||
to: /app/ccd.tpl
|
|
||||||
stageDependencies:
|
|
||||||
setup:
|
|
||||||
- "*"
|
|
||||||
ansible:
|
|
||||||
install:
|
|
||||||
- name: Install packages
|
|
||||||
apk:
|
|
||||||
name:
|
|
||||||
- easy-rsa
|
|
||||||
- bash
|
|
||||||
- name: Create symbolic link for easy-rsa
|
|
||||||
file:
|
|
||||||
src: "/usr/share/easy-rsa/easyrsa"
|
|
||||||
dest: "/usr/local/bin/easyrsa"
|
|
||||||
state: link
|
|
||||||
|
|
||||||
---
|
|
||||||
image: openvpn
|
|
||||||
from: alpine:3.11
|
|
||||||
git:
|
|
||||||
- add: /.werffiles/
|
|
||||||
to: /etc/openvpn/setup/
|
|
||||||
stageDependencies:
|
|
||||||
install:
|
|
||||||
- "*"
|
|
||||||
ansible:
|
|
||||||
install:
|
|
||||||
- name: Install packages
|
|
||||||
apk:
|
|
||||||
name:
|
|
||||||
- openvpn
|
|
||||||
- easy-rsa
|
|
||||||
- name: Create symbolic link for easy-rsa
|
|
||||||
file:
|
|
||||||
src: "/usr/share/easy-rsa/easyrsa"
|
|
||||||
dest: "/usr/local/bin/easyrsa"
|
|
||||||
state: link
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue