Fixed slave server crashed issue if the master is unvailable
This commit is contained in:
parent
9f8098ab03
commit
bf37066475
5 changed files with 77 additions and 19 deletions
|
@ -8,8 +8,8 @@ if [ -e "$SERVER_CERT" ]; then
|
||||||
echo "Found existing certs - reusing"
|
echo "Found existing certs - reusing"
|
||||||
else
|
else
|
||||||
if [ ${OPVN_ROLE:-"master"} = "slave" ]; then
|
if [ ${OPVN_ROLE:-"master"} = "slave" ]; then
|
||||||
echo "Waiting for syncing data from master"
|
echo "Waiting for initial sync data from master"
|
||||||
while [ $(wget -q localhost/api/sync/last -O - | wc -m) -lt 1 ]
|
while [ $(wget -q localhost/api/sync/last/try -O - | wc -m) -lt 1 ]
|
||||||
do
|
do
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|
26
README.md
26
README.md
|
@ -1 +1,25 @@
|
||||||
# openvpn-web-ui
|
# openvpn-admin
|
||||||
|
```
|
||||||
|
usage: openvpn-admin [<flags>]
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
--help Show context-sensitive help (also try --help-long and --help-man).
|
||||||
|
--listen.host="0.0.0.0" host(s) for openvpn-admin
|
||||||
|
--listen.port="8080" port for openvpn-admin
|
||||||
|
--role="master" server role master or slave
|
||||||
|
--master.host="http://127.0.0.1" url for master server
|
||||||
|
--master.basic-auth.user="" user for basic auth on master server url
|
||||||
|
--master.basic-auth.password="" password for basic auth on master server url
|
||||||
|
--master.sync-frequency=600 master host data sync frequency in seconds.
|
||||||
|
--master.sync-token=TOKEN master host data sync security token
|
||||||
|
--ovpn.host=HOST:PORT ... host for openvpn server
|
||||||
|
--ovpn.network="172.16.100.0/24" network for openvpn server
|
||||||
|
--mgmt.host="127.0.0.1" host for openvpn server mgmt interface
|
||||||
|
--mgmt.port="8989" port for openvpn server mgmt interface
|
||||||
|
--easyrsa.path="/mnt/easyrsa" path to easyrsa dir
|
||||||
|
--easyrsa.index-path="/mnt/easyrsa/pki/index.txt"
|
||||||
|
path to easyrsa index file.
|
||||||
|
--ccd.path="/mnt/ccd" path to client-config-dir
|
||||||
|
--static.path="./static" path to static dir
|
||||||
|
--debug Enable debug mode.
|
||||||
|
```
|
2
ccd.tpl
2
ccd.tpl
|
@ -2,5 +2,5 @@
|
||||||
ifconfig-push {{ .ClientAddress }} 255.255.255.255
|
ifconfig-push {{ .ClientAddress }} 255.255.255.255
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- range $route := .CustomRoutes }}
|
{{- range $route := .CustomRoutes }}
|
||||||
push "route {{ $route.Address }} {{ $route.Mask }}" # {{ $route.Description }}
|
push "route {{ $route.Address }} {{ $route.Mask }}" ; {{ $route.Description }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
@ -262,7 +262,7 @@ new Vue({
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.serverRole = response.data.serverRole;
|
_this.serverRole = response.data.serverRole;
|
||||||
if (_this.serverRole == "slave") {
|
if (_this.serverRole == "slave") {
|
||||||
axios.request(axios_cfg('api/sync/last'))
|
axios.request(axios_cfg('api/sync/last/successful'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.lastSync = response.data;
|
_this.lastSync = response.data;
|
||||||
});
|
});
|
||||||
|
|
58
main.go
58
main.go
|
@ -28,12 +28,12 @@ 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()
|
||||||
masterHost = kingpin.Flag("master.host","Url for master server").Default("http://127.0.0.1").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()
|
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()
|
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").Required().String()
|
masterSyncToken = kingpin.Flag("master.sync-token", "master host data sync security token").Default("justasimpleword").PlaceHolder("TOKEN").String()
|
||||||
openvpnServer = kingpin.Flag("ovpn.host","host for openvpn server").Default("127.0.0.1:7777").PlaceHolder("HOST:PORT").Strings()
|
openvpnServer = kingpin.Flag("ovpn.host","host(s) for openvpn server").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()
|
||||||
mgmtListenHost = kingpin.Flag("mgmt.host","host for openvpn server mgmt interface").Default("127.0.0.1").String()
|
mgmtListenHost = kingpin.Flag("mgmt.host","host for openvpn server mgmt interface").Default("127.0.0.1").String()
|
||||||
mgmtListenPort = kingpin.Flag("mgmt.port","port for openvpn server mgmt interface").Default("8989").String()
|
mgmtListenPort = kingpin.Flag("mgmt.port","port for openvpn server mgmt interface").Default("8989").String()
|
||||||
|
@ -46,7 +46,8 @@ var (
|
||||||
certsArchivePath = "/tmp/" + certsArchiveFileName
|
certsArchivePath = "/tmp/" + certsArchiveFileName
|
||||||
ccdArchivePath = "/tmp/" + ccdArchiveFileName
|
ccdArchivePath = "/tmp/" + ccdArchiveFileName
|
||||||
lastSyncTime = ""
|
lastSyncTime = ""
|
||||||
masterHostBsicAuth = false
|
lastSuccessfulSyncTime = ""
|
||||||
|
masterHostBasicAuth = false
|
||||||
)
|
)
|
||||||
|
|
||||||
type OpenvpnServer struct {
|
type OpenvpnServer struct {
|
||||||
|
@ -198,6 +199,10 @@ func lastSyncTimeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprint(w, lastSyncTime)
|
fmt.Fprint(w, lastSyncTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lastSuccessfulSyncTimeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprint(w, lastSuccessfulSyncTime)
|
||||||
|
}
|
||||||
|
|
||||||
func downloadCertsHandler(w http.ResponseWriter, r *http.Request) {
|
func downloadCertsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if *serverRole == "slave" {
|
if *serverRole == "slave" {
|
||||||
http.Error(w, `{"status":"error"}`, http.StatusLocked)
|
http.Error(w, `{"status":"error"}`, http.StatusLocked)
|
||||||
|
@ -238,7 +243,7 @@ func main() {
|
||||||
kingpin.Parse()
|
kingpin.Parse()
|
||||||
|
|
||||||
if *masterBasicAuthPassword != "" && *masterBasicAuthUser != "" {
|
if *masterBasicAuthPassword != "" && *masterBasicAuthUser != "" {
|
||||||
masterHostBsicAuth = true
|
masterHostBasicAuth = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Bind: http://" + *listenHost + ":" + *listenPort)
|
fmt.Println("Bind: http://" + *listenHost + ":" + *listenPort)
|
||||||
|
@ -261,7 +266,8 @@ func main() {
|
||||||
http.HandleFunc("/api/user/ccd", userShowCcdHandler)
|
http.HandleFunc("/api/user/ccd", userShowCcdHandler)
|
||||||
http.HandleFunc("/api/user/ccd/apply", userApplyCcdHandler)
|
http.HandleFunc("/api/user/ccd/apply", userApplyCcdHandler)
|
||||||
|
|
||||||
http.HandleFunc("/api/sync/last", lastSyncTimeHandler)
|
http.HandleFunc("/api/sync/last/try", lastSyncTimeHandler)
|
||||||
|
http.HandleFunc("/api/sync/last/successful", lastSuccessfulSyncTimeHandler)
|
||||||
http.HandleFunc(downloadCertsApiUrl, downloadCertsHandler)
|
http.HandleFunc(downloadCertsApiUrl, downloadCertsHandler)
|
||||||
http.HandleFunc(downloadCcdApiUrl, downloadCddHandler)
|
http.HandleFunc(downloadCcdApiUrl, downloadCddHandler)
|
||||||
|
|
||||||
|
@ -659,9 +665,9 @@ func downloadCerts() bool {
|
||||||
if fExist(certsArchivePath) {
|
if fExist(certsArchivePath) {
|
||||||
fDelete(certsArchivePath)
|
fDelete(certsArchivePath)
|
||||||
}
|
}
|
||||||
err := fDownload(certsArchivePath, *masterHost + downloadCertsApiUrl + "?token=" + *masterSyncToken, masterHostBsicAuth)
|
err := fDownload(certsArchivePath, *masterHost + downloadCertsApiUrl + "?token=" + *masterSyncToken, masterHostBasicAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,9 +679,9 @@ func downloadCcd() bool {
|
||||||
fDelete(ccdArchivePath)
|
fDelete(ccdArchivePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := fDownload(ccdArchivePath, *masterHost + downloadCcdApiUrl + "?token=" + *masterSyncToken, masterHostBsicAuth)
|
err := fDownload(ccdArchivePath, *masterHost + downloadCcdApiUrl + "?token=" + *masterSyncToken, masterHostBasicAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Println(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,13 +711,41 @@ func unArchiveCcd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func syncDataFromMaster() {
|
func syncDataFromMaster() {
|
||||||
downloadCerts()
|
log.Println("Downloading archives from master")
|
||||||
downloadCcd()
|
retryCountMax := 3
|
||||||
|
|
||||||
|
certsDownloadFailed := true
|
||||||
|
ccdDownloadFailed := true
|
||||||
|
|
||||||
|
certsDownloadRetries := 0
|
||||||
|
ccdDownloadRetries := 0
|
||||||
|
|
||||||
|
for certsDownloadFailed && certsDownloadRetries < retryCountMax {
|
||||||
|
certsDownloadRetries += 1
|
||||||
|
if downloadCerts() {
|
||||||
|
certsDownloadFailed = false
|
||||||
|
log.Println("Decompression certs archive from master")
|
||||||
unArchiveCerts()
|
unArchiveCerts()
|
||||||
|
} else {
|
||||||
|
log.Printf("WARNING: something goes wrong during downloading certs from master. Attempt %d", certsDownloadRetries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ccdDownloadFailed && ccdDownloadRetries < retryCountMax {
|
||||||
|
ccdDownloadRetries += 1
|
||||||
|
if downloadCcd() {
|
||||||
|
ccdDownloadFailed = false
|
||||||
|
log.Println("Decompression ccd archive from master")
|
||||||
unArchiveCcd()
|
unArchiveCcd()
|
||||||
|
} else {
|
||||||
|
log.Printf("WARNING: something goes wrong during downloading certs from master. Attempt %d", ccdDownloadRetries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lastSyncTime = time.Now().Format("2006-01-02 15:04:05")
|
lastSyncTime = time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
if !ccdDownloadFailed && !certsDownloadFailed {
|
||||||
|
lastSuccessfulSyncTime = time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func syncWithMaster() {
|
func syncWithMaster() {
|
||||||
|
|
Loading…
Reference in a new issue