frp
frp copied to clipboard
[Feature Request] Allow frpc config update via frps
Describe the feature request
Thank you for this superb tool. We already have the functionality to update the config of a frpc instance via the adminUI, which is great! But you need to have direct access to the frpc server or you need to setup a proxy configuration to each frpc you have It would be awesome if we could have a feature to execute a configuration update from the frps dashboard (or some other adminUI on frps). It would reduce the number of ports that need to be actively mananged.
Describe alternatives you've considered
Setup a proxy configuration to each frpc to update the configuration.
Affected area
- [ ] Docs
- [ ] Installation
- [X] Performance and Scalability
- [ ] Security
- [X] User Experience
- [ ] Test and Release
- [ ] Developer Infrastructure
- [ ] Client Plugin
- [ ] Server Plugin
- [ ] Extensions
- [ ] Others
https://github.com/fatedier/frp/issues/1570
v0.31.0 已支持服务端插件,可以自行实现。
Planned in frp v2, we want to support multiple configure registry such as static file, remote url, etc.
Add in service.go
add in import
"net/http" //TheFantas
"os" //TheFantas
"os/exec" //TheFantas
"path/filepath" //TheFantas
"syscall" //TheFantas
goversion "github.com/hashicorp/go-version" //TheFantas
"github.com/minio/selfupdate" //TheFantas
log.Info("admin server listen on %s:%d", svr.cfg.AdminAddr, svr.cfg.AdminPort)
//Add TheFantas
ex, err1 := os.Executable()
if err1 != nil {
panic(err1)
}
name_file := fmt.Sprintf("frpc_%s_%s%s", runtime.GOOS, runtime.GOARCH, filepath.Ext(ex))
log.Info("Current Version: %s", version.Full())
log.Info("Checking new version... %s", name_file)
v1, err2 := goversion.NewVersion(version.Full())
resp, err3 := http.Get("https://website.xyz/frp/frp.php?v=ok")
if err3 != nil {
return err3
}
defer resp.Body.Close()
resBody, err := io.ReadAll(resp.Body)
v2, err2 := goversion.NewVersion(fmt.Sprintf("%s", resBody))
log.Info("Respuesta: %s", resBody)
if err2 != nil {
log.Warn("Error2: %v", err2)
} else {
if v1.LessThan(v2) {
log.Info("%s is less than %s", v1, v2)
log.Info("Updating...")
svr.doUpdate(fmt.Sprintf("https://website.xyz/frp/%s", name_file))
} else {
log.Info("You have the latest version.")
}
}
add function
// Add TheFantas
func (svr *Service) doUpdate(url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
err = selfupdate.Apply(resp.Body, selfupdate.Options{
//TargetPath: "/root/frp/bin/test",
})
if err != nil {
// error handling
log.Info("%v", err)
if rerr := selfupdate.RollbackError(err); rerr != nil {
log.Info("Failed to rollback from bad update: %v", rerr)
}
} else {
log.Info("update completed.")
svr.restartProcess()
svr.restart()
}
return err
}
frp.php
<?php
header("Pragma-directive: no-cache");
header("Cache-directive: no-cache");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-Transfer-Encoding: text/plain");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
$version = $_GET['v'];
if ($version == 'ok')
echo '0.51.2';
2023/08/07 15:27:02 [I] [service.go:170] admin server listen on 127.0.0.1:7400
2023/08/07 15:27:02 [I] [service.go:178] Current Version: 0.51.2
2023/08/07 15:27:02 [I] [service.go:179] Checking new version... frpc_linux_amd64
2023/08/07 15:27:03 [I] [service.go:199] You have the latest version.