mirror of
https://github.com/flant/ovpn-admin.git
synced 2026-02-04 09:12:13 -08:00
Compare commits
3 Commits
2103502912
...
3fbdd8e646
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fbdd8e646 | ||
|
|
ac96942e1d | ||
|
|
5dd44dad7f |
@ -9,7 +9,7 @@ COPY . /app
|
|||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
RUN cd /app && packr2 && env CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build -a -tags netgo -ldflags '-linkmode external -extldflags -static -s -w' -o ovpn-admin && packr2 clean
|
RUN cd /app && packr2 && env CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build -a -tags netgo -ldflags '-linkmode external -extldflags -static -s -w' -o ovpn-admin && packr2 clean
|
||||||
|
|
||||||
FROM alpine:3.16
|
FROM alpine:3.19
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=backend-builder /app/ovpn-admin /app
|
COPY --from=backend-builder /app/ovpn-admin /app
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
@ -17,4 +17,4 @@ RUN apk add --update bash easy-rsa openssl openvpn coreutils && \
|
|||||||
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.4/openvpn-user-linux-${TARGETARCH}.tar.gz -O - | tar xz -C /usr/local/bin && \
|
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.4/openvpn-user-linux-${TARGETARCH}.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/*
|
||||||
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
FROM alpine:3.16
|
FROM alpine:3.19
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
RUN apk add --update bash openvpn easy-rsa iptables && \
|
RUN apk add --update bash openvpn easy-rsa iptables && \
|
||||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
||||||
@ -6,4 +6,4 @@ RUN apk add --update bash openvpn easy-rsa iptables && \
|
|||||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||||
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
||||||
COPY setup/ /etc/openvpn/setup
|
COPY setup/ /etc/openvpn/setup
|
||||||
RUN chmod +x /etc/openvpn/setup/configure.sh
|
RUN chmod +x /etc/openvpn/setup/configure.sh
|
||||||
|
|||||||
@ -157,7 +157,10 @@ Flags:
|
|||||||
|
|
||||||
--auth.db="./easyrsa/pki/users.db"
|
--auth.db="./easyrsa/pki/users.db"
|
||||||
(or OVPN_AUTH_DB_PATH) database path for password authorization
|
(or OVPN_AUTH_DB_PATH) database path for password authorization
|
||||||
|
|
||||||
|
--auth.db-init
|
||||||
|
(or OVPN_AUTH_DB_INIT) enable database init if user db not exists or size is 0
|
||||||
|
|
||||||
--log.level set log level: trace, debug, info, warn, error (default info)
|
--log.level set log level: trace, debug, info, warn, error (default info)
|
||||||
(or LOG_LEVEL)
|
(or LOG_LEVEL)
|
||||||
|
|
||||||
|
|||||||
63
main.go
63
main.go
@ -9,11 +9,7 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/uuid"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/client-go/kubernetes"
|
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -25,6 +21,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
"github.com/gobuffalo/packr/v2"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
@ -71,6 +72,7 @@ var (
|
|||||||
ccdTemplatePath = kingpin.Flag("templates.ccd-path", "path to custom ccd.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 authentication").Default("false").Envar("OVPN_AUTH").Bool()
|
authByPassword = kingpin.Flag("auth.password", "enable additional password authentication").Default("false").Envar("OVPN_AUTH").Bool()
|
||||||
authDatabase = kingpin.Flag("auth.db", "database path for password authentication").Default("./easyrsa/pki/users.db").Envar("OVPN_AUTH_DB_PATH").String()
|
authDatabase = kingpin.Flag("auth.db", "database path for password authentication").Default("./easyrsa/pki/users.db").Envar("OVPN_AUTH_DB_PATH").String()
|
||||||
|
authDataBaseInit = kingpin.Flag("auth.db-init", "enable database initialization if db user not exists or size is 0").Default("false").Envar("OVPN_AUTH_DB_INIT").Bool()
|
||||||
logLevel = kingpin.Flag("log.level", "set log level: trace, debug, info, warn, error (default info)").Default("info").Envar("LOG_LEVEL").String()
|
logLevel = kingpin.Flag("log.level", "set log level: trace, debug, info, warn, error (default info)").Default("info").Envar("LOG_LEVEL").String()
|
||||||
logFormat = kingpin.Flag("log.format", "set log format: text, json (default text)").Default("text").Envar("LOG_FORMAT").String()
|
logFormat = kingpin.Flag("log.format", "set log format: text, json (default text)").Default("text").Envar("LOG_FORMAT").String()
|
||||||
storageBackend = kingpin.Flag("storage.backend", "storage backend: filesystem, kubernetes.secrets (default filesystem)").Default("filesystem").Envar("STORAGE_BACKEND").String()
|
storageBackend = kingpin.Flag("storage.backend", "storage backend: filesystem, kubernetes.secrets (default filesystem)").Default("filesystem").Envar("STORAGE_BACKEND").String()
|
||||||
@ -504,6 +506,10 @@ func main() {
|
|||||||
*indexTxtPath = *easyrsaDirPath + "/pki/index.txt"
|
*indexTxtPath = *easyrsaDirPath + "/pki/index.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *authDataBaseInit {
|
||||||
|
ovpnUserInitDb()
|
||||||
|
}
|
||||||
|
|
||||||
ovpnAdmin := new(OvpnAdmin)
|
ovpnAdmin := new(OvpnAdmin)
|
||||||
|
|
||||||
ovpnAdmin.lastSyncTime = "unknown"
|
ovpnAdmin.lastSyncTime = "unknown"
|
||||||
@ -558,27 +564,27 @@ func main() {
|
|||||||
static := CacheControlWrapper(http.FileServer(staticBox))
|
static := CacheControlWrapper(http.FileServer(staticBox))
|
||||||
|
|
||||||
http.Handle(*listenBaseUrl, http.StripPrefix(strings.TrimRight(*listenBaseUrl, "/"), static))
|
http.Handle(*listenBaseUrl, http.StripPrefix(strings.TrimRight(*listenBaseUrl, "/"), static))
|
||||||
http.HandleFunc(*listenBaseUrl + "api/server/settings", ovpnAdmin.serverSettingsHandler)
|
http.HandleFunc(*listenBaseUrl+"api/server/settings", ovpnAdmin.serverSettingsHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/users/list", ovpnAdmin.userListHandler)
|
http.HandleFunc(*listenBaseUrl+"api/users/list", ovpnAdmin.userListHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/create", ovpnAdmin.userCreateHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/create", ovpnAdmin.userCreateHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/change-password", ovpnAdmin.userChangePasswordHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/change-password", ovpnAdmin.userChangePasswordHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/rotate", ovpnAdmin.userRotateHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/rotate", ovpnAdmin.userRotateHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/delete", ovpnAdmin.userDeleteHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/delete", ovpnAdmin.userDeleteHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/revoke", ovpnAdmin.userRevokeHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/revoke", ovpnAdmin.userRevokeHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/unrevoke", ovpnAdmin.userUnrevokeHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/unrevoke", ovpnAdmin.userUnrevokeHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/config/show", ovpnAdmin.userShowConfigHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/config/show", ovpnAdmin.userShowConfigHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/disconnect", ovpnAdmin.userDisconnectHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/disconnect", ovpnAdmin.userDisconnectHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/statistic", ovpnAdmin.userStatisticHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/statistic", ovpnAdmin.userStatisticHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/ccd", ovpnAdmin.userShowCcdHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/ccd", ovpnAdmin.userShowCcdHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/user/ccd/apply", ovpnAdmin.userApplyCcdHandler)
|
http.HandleFunc(*listenBaseUrl+"api/user/ccd/apply", ovpnAdmin.userApplyCcdHandler)
|
||||||
|
|
||||||
http.HandleFunc(*listenBaseUrl + "api/sync/last/try", ovpnAdmin.lastSyncTimeHandler)
|
http.HandleFunc(*listenBaseUrl+"api/sync/last/try", ovpnAdmin.lastSyncTimeHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + "api/sync/last/successful", ovpnAdmin.lastSuccessfulSyncTimeHandler)
|
http.HandleFunc(*listenBaseUrl+"api/sync/last/successful", ovpnAdmin.lastSuccessfulSyncTimeHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + downloadCertsApiUrl, ovpnAdmin.downloadCertsHandler)
|
http.HandleFunc(*listenBaseUrl+downloadCertsApiUrl, ovpnAdmin.downloadCertsHandler)
|
||||||
http.HandleFunc(*listenBaseUrl + downloadCcdApiUrl, ovpnAdmin.downloadCcdHandler)
|
http.HandleFunc(*listenBaseUrl+downloadCcdApiUrl, ovpnAdmin.downloadCcdHandler)
|
||||||
|
|
||||||
http.Handle(*metricsPath, promhttp.HandlerFor(ovpnAdmin.promRegistry, promhttp.HandlerOpts{}))
|
http.Handle(*metricsPath, promhttp.HandlerFor(ovpnAdmin.promRegistry, promhttp.HandlerOpts{}))
|
||||||
http.HandleFunc(*listenBaseUrl + "ping", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(*listenBaseUrl+"ping", func(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, "pong")
|
fmt.Fprintf(w, "pong")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1053,7 +1059,7 @@ func (oAdmin *OvpnAdmin) userRevoke(username string) (error, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *authByPassword {
|
if *authByPassword {
|
||||||
o := runBash(fmt.Sprintf("openvpn-user revoke --db-path %s --user %s", *authDatabase, username))
|
o := runBash(fmt.Sprintf("openvpn-user revoke --db.path %s --user %s", *authDatabase, username))
|
||||||
log.Debug(o)
|
log.Debug(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,7 +1121,7 @@ func (oAdmin *OvpnAdmin) userUnrevoke(username string) (error, string) {
|
|||||||
_ = runBash(fmt.Sprintf("cd %s && %s gen-crl 1>/dev/null", *easyrsaDirPath, *easyrsaBinPath))
|
_ = runBash(fmt.Sprintf("cd %s && %s gen-crl 1>/dev/null", *easyrsaDirPath, *easyrsaBinPath))
|
||||||
|
|
||||||
if *authByPassword {
|
if *authByPassword {
|
||||||
o := runBash(fmt.Sprintf("openvpn-user restore --db-path %s --user %s", *authDatabase, username))
|
o := runBash(fmt.Sprintf("openvpn-user restore --db.path %s --user %s", *authDatabase, username))
|
||||||
log.Debug(o)
|
log.Debug(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1340,7 +1346,7 @@ func (oAdmin *OvpnAdmin) mgmtGetActiveClients() []clientStatus {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
oAdmin.mgmtRead(conn) // read welcome message
|
oAdmin.mgmtRead(conn) // read welcome message
|
||||||
conn.Write([]byte("status\n"))
|
conn.Write([]byte("status 1\n"))
|
||||||
activeClients = append(activeClients, oAdmin.mgmtConnectedUsersParser(oAdmin.mgmtRead(conn), srv)...)
|
activeClients = append(activeClients, oAdmin.mgmtConnectedUsersParser(oAdmin.mgmtRead(conn), srv)...)
|
||||||
conn.Close()
|
conn.Close()
|
||||||
}
|
}
|
||||||
@ -1501,6 +1507,13 @@ func unArchiveCcd() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ovpnUserInitDb() {
|
||||||
|
if fi, err := os.Stat(*authDatabase); errors.Is(err, os.ErrNotExist) || fi.Size() == 0 {
|
||||||
|
i := runBash(fmt.Sprintf("openvpn-user --db.path %[1]s db-init && openvpn-user --db.path %[1]s db-migrate", *authDatabase))
|
||||||
|
log.Debug(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (oAdmin *OvpnAdmin) syncDataFromMaster() {
|
func (oAdmin *OvpnAdmin) syncDataFromMaster() {
|
||||||
retryCountMax := 3
|
retryCountMax := 3
|
||||||
certsDownloadFailed := true
|
certsDownloadFailed := true
|
||||||
|
|||||||
@ -48,7 +48,7 @@ if [ ${OVPN_PASSWD_AUTH} = "true" ]; then
|
|||||||
echo "auth-user-pass-verify /etc/openvpn/scripts/auth.sh via-file" | tee -a /etc/openvpn/openvpn.conf
|
echo "auth-user-pass-verify /etc/openvpn/scripts/auth.sh via-file" | tee -a /etc/openvpn/openvpn.conf
|
||||||
echo "script-security 2" | tee -a /etc/openvpn/openvpn.conf
|
echo "script-security 2" | tee -a /etc/openvpn/openvpn.conf
|
||||||
echo "verify-client-cert require" | tee -a /etc/openvpn/openvpn.conf
|
echo "verify-client-cert require" | tee -a /etc/openvpn/openvpn.conf
|
||||||
openvpn-user db-init --db.path=$EASY_RSA_LOC/pki/users.db
|
openvpn-user db-init --db.path=$EASY_RSA_LOC/pki/users.db && openvpn-user db-migrate --db.path=$EASY_RSA_LOC/pki/users.db
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -d $EASY_RSA_LOC/pki ] && chmod 755 $EASY_RSA_LOC/pki
|
[ -d $EASY_RSA_LOC/pki ] && chmod 755 $EASY_RSA_LOC/pki
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user