Skip to content

Commit

Permalink
Merge pull request #1 from pashcovich/draft-password-auth
Browse files Browse the repository at this point in the history
Additional password auth
Multiple mgmt interface usgae
Layout changes
Small fixes
  • Loading branch information
pashcovich authored Feb 20, 2021
2 parents 0af5fc3 + 3614ab6 commit 3db7576
Show file tree
Hide file tree
Showing 16 changed files with 366 additions and 227 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ frontend/node_modules
openvpn-web-ui
openvpn-ui
openvpn-admin

docker-compose.yaml
docker-compose-slave.yaml
11 changes: 5 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
FROM golang:1.14.2-alpine3.11 AS backend-builder
FROM golang:1.14.2-buster AS backend-builder
COPY . /app
#RUN apk --no-cache add build-base git gcc
RUN cd /app && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
RUN cd /app && env CGO_ENABLED=./1 GOOS=linux GOARCH=amd64 go build -ldflags='-linkmode external -extldflags "-static" -s -w' -o openvpn-admin

FROM node:14.2-alpine3.11 AS frontend-builder
COPY frontend/ /app
RUN cd /app && npm install && npm run build

FROM alpine:3.11
FROM alpine:3.13
WORKDIR /app
COPY --from=backend-builder /app/openvpn-admin /app
COPY --from=frontend-builder /app/static /app/static
COPY client.conf.tpl /app/client.conf.tpl
COPY ccd.tpl /app/ccd.tpl
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
apk add --update bash easy-rsa && \
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 && \
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
8 changes: 4 additions & 4 deletions Dockerfile.openvpn
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM alpine:3.11
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
apk add --update bash openvpn easy-rsa && \
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 && \
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
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/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
15 changes: 12 additions & 3 deletions client.conf.tpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{- range $server := .Hosts }}
remote {{ $server.Host }} {{ $server.Port }} tcp
remote {{ $server.Host }} {{ $server.Port }} {{ $server.Protocol }}
{{- end }}

verb 4
Expand All @@ -11,10 +11,19 @@ key-direction 1
#redirect-gateway def1
tls-client
remote-cert-tls server
# for update resolv.conf on ubuntu
#script-security 2 system
# uncomment needed below lines for use with linux
#script-security 2
# if use use resolved
#up /etc/openvpn/update-resolv-conf
#down /etc/openvpn/update-resolv-conf
# if you use systemd-resolved first install and openvpn-systemd-resolved package
#up /etc/openvpn/update-systemd-resolved
#down /etc/openvpn/update-systemd-resolved

{{- if .PasswdAuth }}
auth-user-pass
{{- end }}

<cert>
{{ .Cert -}}
</cert>
Expand Down
3 changes: 2 additions & 1 deletion docker-compose-slave.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ services:
image: openvpn:local
command: /etc/openvpn/setup/configure.sh
environment:
- OPVN_PASSWD_AUTH=true
- OPVN_ROLE=slave
cap_add:
- NET_ADMIN
Expand All @@ -21,7 +22,7 @@ services:
build:
context: .
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"
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:
- OPVN_SLAVE=1
network_mode: service:openvpn
Expand Down
4 changes: 3 additions & 1 deletion docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ services:
dockerfile: Dockerfile.openvpn
image: openvpn:local
command: /etc/openvpn/setup/configure.sh
environment:
- OPVN_PASSWD_AUTH=true
cap_add:
- NET_ADMIN
ports:
Expand All @@ -19,7 +21,7 @@ services:
build:
context: .
image: openvpn-admin:local
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN"
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --auth.password
network_mode: service:openvpn
volumes:
- ./easyrsa_master:/mnt/easyrsa
Expand Down
5 changes: 5 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"vue": "^2.6.12",
"vue-clipboard2": "^0.2.1",
"vue-cookies": "^1.7.4",
"vue-good-table": "^2.21.1"
"vue-good-table": "^2.21.1",
"vue-notification": "^1.3.20"
},
"browserslist": [
"> 1%",
Expand Down
100 changes: 89 additions & 11 deletions frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import axios from 'axios';
import VueCookies from 'vue-cookies'
import VueClipboard from 'vue-clipboard2'
import VueGoodTablePlugin from 'vue-good-table'
import Notifications from 'vue-notification'

import 'vue-good-table/dist/vue-good-table.css'

Vue.use(VueClipboard)
Vue.use(VueGoodTablePlugin)
Vue.use(VueCookies)
Vue.use(Notifications)

var axios_cfg = function(url, data='', type='form') {
if (data == '') {
Expand Down Expand Up @@ -54,6 +56,11 @@ new Vue({
field: 'AccountStatus',
filterable: true,
},
{
label: 'Connection Server',
field: 'ConnectionServer',
filterable: true,
},
{
label: 'Expiration Date',
field: 'ExpirationDate',
Expand Down Expand Up @@ -84,39 +91,52 @@ new Vue({
],
rows: [],
actions: [
{
name: 'u-change-password',
label: 'Change password',
class: 'btn-warning',
showWhenStatus: 'Active',
showForServerRole: ['master']
},
{
name: 'u-revoke',
label: 'Revoke',
class: 'btn-warning',
showWhenStatus: 'Active',
showForServerRole: ['master']
},
{
name: 'u-unrevoke',
label: 'Unrevoke',
class: 'btn-primary',
showWhenStatus: 'Revoked',
showForServerRole: ['master']
},
{
name: 'u-show-config',
label: 'Show config',
showWhenStatus: 'Active',
showForServerRole: ['master', 'slave']
},
// {
// name: 'u-show-config',
// label: 'Show config',
// class: 'btn-primary',
// showWhenStatus: 'Active',
// showForServerRole: ['master', 'slave']
// },
{
name: 'u-download-config',
label: 'Download config',
class: 'btn-info',
showWhenStatus: 'Active',
showForServerRole: ['master', 'slave']
},
{
name: 'u-edit-ccd',
label: 'Edit routes',
class: 'btn-primary',
showWhenStatus: 'Active',
showForServerRole: ['master']
},
{
name: 'u-edit-ccd',
label: 'Show routes',
class: 'btn-primary',
showWhenStatus: 'Active',
showForServerRole: ['slave']
}
Expand All @@ -128,11 +148,15 @@ new Vue({
lastSync: "unknown",
u: {
newUserName: '',
// newUserPassword: 'nopass',
newUserPassword: '',
newUserCreateError: '',
newPassword: '',
passwordChangeStatus: '',
passwordChangeMessage: '',
modalNewUserVisible: false,
modalShowConfigVisible: false,
modalShowCcdVisible: false,
modalChangePasswordVisible: false,
openvpnConfig: '',
ccd: {
Name: '',
Expand Down Expand Up @@ -160,6 +184,7 @@ new Vue({
axios.request(axios_cfg('api/user/revoke', data, 'form'))
.then(function(response) {
_this.getUserData();
_this.$notify({title: 'User ' + _this.username + ' revoked!', type: 'warn'})
});
})
_this.$root.$on('u-unrevoke', function () {
Expand All @@ -168,6 +193,7 @@ new Vue({
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
.then(function(response) {
_this.getUserData();
_this.$notify({title: 'User ' + _this.username + ' unrevoked!', type: 'success'})
});
})
_this.$root.$on('u-show-config', function () {
Expand Down Expand Up @@ -210,6 +236,11 @@ new Vue({
console.log(response.data);
});
})
_this.$root.$on('u-change-password', function () {
_this.u.modalChangePasswordVisible = true;
var data = new URLSearchParams();
data.append('username', _this.username);
})
},
computed: {
customAddressDisabled: function () {
Expand All @@ -218,6 +249,9 @@ new Vue({
ccdApplyStatusCssClass: function () {
return this.u.ccdApplyStatus == 200 ? "alert-success" : "alert-danger"
},
passwordChangeStatusCssClass: function () {
return this.u.passwordChangeStatus == 200 ? "alert-success" : "alert-danger"
},
modalNewUserDisplay: function () {
return this.u.modalNewUserVisible ? {display: 'flex'} : {}
},
Expand All @@ -227,6 +261,9 @@ new Vue({
modalShowCcdDisplay: function () {
return this.u.modalShowCcdVisible ? {display: 'flex'} : {}
},
modalChangePasswordDisplay: function () {
return this.u.modalChangePasswordVisible ? {display: 'flex'} : {}
},
revokeFilterText: function() {
return this.filters.hideRevoked ? "Show revoked" : "Hide revoked"
},
Expand Down Expand Up @@ -256,6 +293,15 @@ new Vue({
_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() {
var _this = this;
axios.request(axios_cfg('api/server/role'))
Expand All @@ -269,26 +315,31 @@ new Vue({
}
});
},

createUser: function() {
var _this = this;

_this.u.newUserCreateError = "";

var data = new URLSearchParams();
data.append('username', _this.u.newUserName);
// data.append('password', this.u.newUserPassword);
data.append('password', _this.u.newUserPassword);

axios.request(axios_cfg('api/user/create', data, 'form'))
.then(function(response) {
_this.getUserData();
_this.u.modalNewUserVisible = false;
_this.u.newUserName = '';
// _this.u.newUserPassword = 'nopass';
_this.u.newUserPassword = '';
_this.getUserData();
_this.$notify({title: 'New user ' + _this.username + ' created', type: 'success'})
})
.catch(function(error) {
_this.u.newUserCreateError = error.response.data;
_this.$notify({title: 'New user ' + _this.username + ' creation failed.', type: 'error'})

});
},

ccdApply: function() {
var _this = this;

Expand All @@ -299,11 +350,38 @@ new Vue({
.then(function(response) {
_this.u.ccdApplyStatus = 200;
_this.u.ccdApplyStatusMessage = response.data;
_this.$notify({title: 'Ccd for user ' + _this.username + ' applied', type: 'success'})
})
.catch(function(error) {
_this.u.ccdApplyStatus = error.response.status;
_this.u.ccdApplyStatusMessage = error.response.data;
_this.$notify({title: 'Ccd for user ' + _this.username + ' apply failed ', type: 'error'})
});
}
},

changeUserPassword: function(user) {
var _this = this;

_this.u.passwordChangeMessage = "";

var data = new URLSearchParams();
data.append('username', user);
data.append('password', _this.u.newPassword);

axios.request(axios_cfg('api/user/change-password', data, 'form'))
.then(function(response) {
_this.u.passwordChangeStatus = 200;
_this.u.newPassword = '';
_this.getUserData();
_this.u.modalChangePasswordVisible = false;
_this.$notify({title: 'Password for user ' + _this.username + ' changed!', type: 'success'})
})
.catch(function(error) {
_this.u.passwordChangeStatus = error.response.status;
_this.u.passwordChangeMessage = error.response.data.message;
_this.$notify({title: 'Changing password for user ' + _this.username + ' failed!', type: 'error'})
});
},
}

})
Loading

0 comments on commit 3db7576

Please sign in to comment.