mirror of
https://github.com/luscis/openlan.git
synced 2025-10-07 01:22:51 +08:00
fix: operate ztrust from user
This commit is contained in:
@@ -127,3 +127,4 @@ OpenLAN提供一种局域网数据报文在广域网的传输实现,并能够
|
||||
- [多区域互联](docs/multiarea.md)
|
||||
- [全互连网络](docs/fabric.md)
|
||||
- [IPSec网络](docs/ipsec.md)
|
||||
- [零信任网络](docs/ztrust.md)
|
||||
|
@@ -124,3 +124,4 @@ If you have more flexible VPN business needs and need to use VPN to access the e
|
||||
- [Multi-region Interconnection](docs/multiarea.md)
|
||||
- [Fullly Interconnected Network](docs/fabric.md)
|
||||
- [IPSec Network](docs/ipsec.md)
|
||||
- [Zero Trust Network](docs/ztrust.md)
|
||||
|
@@ -13,6 +13,14 @@ func GetEnv(key, value string) string {
|
||||
return val
|
||||
}
|
||||
|
||||
func GetUser(name string) string {
|
||||
values := strings.SplitN(name, ":", 2)
|
||||
if strings.Contains(values[0], "@") {
|
||||
return values[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func SplitName(name string) (string, string) {
|
||||
values := strings.SplitN(name, "@", 2)
|
||||
if len(values) == 2 {
|
||||
|
@@ -3,10 +3,12 @@ package v5
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/luscis/openlan/cmd/api"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/luscis/openlan/cmd/api"
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
@@ -104,9 +106,16 @@ type Cmd struct {
|
||||
}
|
||||
|
||||
func (c Cmd) NewHttp(token string) Client {
|
||||
values := strings.SplitN(token, ":", 2)
|
||||
username := values[0]
|
||||
password := values[0]
|
||||
if len(values) == 2 {
|
||||
password = values[1]
|
||||
}
|
||||
client := Client{
|
||||
Auth: libol.Auth{
|
||||
Username: token,
|
||||
Username: username,
|
||||
Password: password,
|
||||
},
|
||||
}
|
||||
return client
|
||||
|
@@ -15,8 +15,8 @@ type Guest struct {
|
||||
|
||||
func (u Guest) Url(prefix, name string) string {
|
||||
name, network := api.SplitName(name)
|
||||
if name == "" {
|
||||
return prefix + "/api/network/" + network + "/guest"
|
||||
if network == "" {
|
||||
return prefix + "/api/network/" + name + "/guest"
|
||||
}
|
||||
return prefix + "/api/network/" + network + "/guest/" + name
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func (u Guest) Tmpl() string {
|
||||
func (u Guest) List(c *cli.Context) error {
|
||||
network := c.String("network")
|
||||
|
||||
url := u.Url(c.String("url"), "@"+network)
|
||||
url := u.Url(c.String("url"), network)
|
||||
clt := u.NewHttp(c.String("token"))
|
||||
|
||||
var items []schema.ZGuest
|
||||
@@ -81,6 +81,7 @@ func (u Guest) List(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func (u Guest) Commands(app *api.App) {
|
||||
name := api.GetUser(api.Token)
|
||||
app.Command(&cli.Command{
|
||||
Name: "guest",
|
||||
Aliases: []string{"gu"},
|
||||
@@ -90,7 +91,7 @@ func (u Guest) Commands(app *api.App) {
|
||||
Name: "add",
|
||||
Usage: "Add a zGuest",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name"},
|
||||
&cli.StringFlag{Name: "name", Value: name},
|
||||
&cli.StringFlag{Name: "address"},
|
||||
},
|
||||
Action: u.Add,
|
||||
@@ -100,7 +101,7 @@ func (u Guest) Commands(app *api.App) {
|
||||
Usage: "Remove an existing zGuest",
|
||||
Aliases: []string{"rm"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name"},
|
||||
&cli.StringFlag{Name: "name", Value: name},
|
||||
&cli.StringFlag{Name: "address"},
|
||||
},
|
||||
Action: u.Remove,
|
||||
@@ -110,7 +111,7 @@ func (u Guest) Commands(app *api.App) {
|
||||
Usage: "Display all zGuests",
|
||||
Aliases: []string{"ls"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "network"},
|
||||
&cli.StringFlag{Name: "network", Value: name},
|
||||
},
|
||||
Action: u.List,
|
||||
},
|
||||
|
@@ -83,6 +83,7 @@ func (u Knock) List(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func (u Knock) Commands(app *api.App) {
|
||||
name := api.GetUser(api.Token)
|
||||
app.Command(&cli.Command{
|
||||
Name: "knock",
|
||||
Aliases: []string{"kn"},
|
||||
@@ -92,7 +93,7 @@ func (u Knock) Commands(app *api.App) {
|
||||
Name: "add",
|
||||
Usage: "Add a knock",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name"},
|
||||
&cli.StringFlag{Name: "name", Value: name},
|
||||
&cli.StringFlag{Name: "protocol"},
|
||||
&cli.StringFlag{Name: "socket"},
|
||||
&cli.IntFlag{Name: "age", Value: 60},
|
||||
@@ -104,7 +105,7 @@ func (u Knock) Commands(app *api.App) {
|
||||
Usage: "Remove an existing knock",
|
||||
Aliases: []string{"rm"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name"},
|
||||
&cli.StringFlag{Name: "name", Value: name},
|
||||
&cli.StringFlag{Name: "protocol"},
|
||||
&cli.StringFlag{Name: "socket"},
|
||||
},
|
||||
@@ -115,7 +116,7 @@ func (u Knock) Commands(app *api.App) {
|
||||
Usage: "Display all knock",
|
||||
Aliases: []string{"ls"},
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "name"},
|
||||
&cli.StringFlag{Name: "name", Value: name},
|
||||
},
|
||||
Action: u.List,
|
||||
},
|
||||
|
42
docs/ztrust.md
Normal file
42
docs/ztrust.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Zero Trust
|
||||
|
||||
## Enable ztrust on a network
|
||||
```
|
||||
$ cat /etc/openlan/switch/network/example.json
|
||||
{
|
||||
...
|
||||
"ztrust": "enable"
|
||||
}
|
||||
$
|
||||
```
|
||||
|
||||
## Add yourself to ztrust
|
||||
```
|
||||
$ export TOKEN="daniel@example:g4nlzmk5nxek1hbcqsbr"
|
||||
$ export URL="https://your-central-switch-address:10000"
|
||||
$ openlan guest add
|
||||
$ openlan guest ls
|
||||
# total 1
|
||||
username address
|
||||
daniel@internal 169.254.15.6
|
||||
$
|
||||
```
|
||||
|
||||
## Knock a host service
|
||||
```
|
||||
$ openlan knock add --protocol icmp --socket 192.168.20.10
|
||||
$ openlan knock add --protocol tcp --socket 192.168.20.10:22
|
||||
$ openlan knock ls
|
||||
# total 2
|
||||
username protocol socket age createAt
|
||||
daniel@internal tcp 192.168.20.10:22 57 2024-01-02 12:42:06 +0000 UTC
|
||||
daniel@internal icmp 192.168.20.10: 46 2024-01-02 12:41:55 +0000 UTC
|
||||
$
|
||||
```
|
||||
|
||||
## Connect to a host service
|
||||
```
|
||||
$ ssh root@192.168.20.10 who
|
||||
root pts/0 2024-01-02 06:49 (100.66.88.1)
|
||||
$
|
||||
```
|
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/luscis/openlan/pkg/cache"
|
||||
@@ -16,12 +17,21 @@ type ZTrust struct {
|
||||
func (h ZTrust) Router(router *mux.Router) {
|
||||
router.HandleFunc("/api/network/{id}/ztrust", h.List).Methods("GET")
|
||||
router.HandleFunc("/api/network/{id}/guest", h.ListGuest).Methods("GET")
|
||||
router.HandleFunc("/api/network/{id}/guest/{user}", h.ListGuest).Methods("GET")
|
||||
router.HandleFunc("/api/network/{id}/guest/{user}", h.AddGuest).Methods("POST")
|
||||
router.HandleFunc("/api/network/{id}/guest/{user}", h.DelGuest).Methods("DELETE")
|
||||
router.HandleFunc("/api/network/{id}/guest/{user}/knock", h.ListKnock).Methods("GET")
|
||||
router.HandleFunc("/api/network/{id}/guest/{user}/knock", h.AddKnock).Methods("POST")
|
||||
}
|
||||
|
||||
func CheckUser(r *http.Request) (bool, string) {
|
||||
user, _, _ := r.BasicAuth()
|
||||
if strings.Contains(user, "@") {
|
||||
return false, strings.SplitN(user, "@", 2)[0]
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (h ZTrust) List(w http.ResponseWriter, r *http.Request) {
|
||||
ResponseJson(w, "TODO")
|
||||
}
|
||||
@@ -47,9 +57,17 @@ func (h ZTrust) ListGuest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
admin, name := CheckUser(r)
|
||||
guests := make([]schema.ZGuest, 0, 1024)
|
||||
ztrust.ListGuest(func(obj schema.ZGuest) {
|
||||
guests = append(guests, obj)
|
||||
if !admin {
|
||||
if obj.Name == name {
|
||||
guests = append(guests, obj)
|
||||
}
|
||||
} else {
|
||||
guests = append(guests, obj)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
ResponseJson(w, guests)
|
||||
@@ -77,7 +95,10 @@ func (h ZTrust) AddGuest(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
guest.Name = vars["user"]
|
||||
libol.Info("ZTrust.AddGuest %s@%s", guest.Name, id)
|
||||
admin, name := CheckUser(r)
|
||||
if !admin {
|
||||
guest.Name = name
|
||||
}
|
||||
if guest.Address == "" {
|
||||
client := cache.VPNClient.Get(id, guest.Name)
|
||||
if client != nil {
|
||||
@@ -85,6 +106,9 @@ func (h ZTrust) AddGuest(w http.ResponseWriter, r *http.Request) {
|
||||
guest.Device = client.Device
|
||||
}
|
||||
}
|
||||
|
||||
libol.Info("ZTrust.AddGuest %s@%s", guest.Name, id)
|
||||
|
||||
if guest.Address == "" {
|
||||
http.Error(w, "invalid address", http.StatusBadRequest)
|
||||
return
|
||||
@@ -120,6 +144,11 @@ func (h ZTrust) DelGuest(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
guest.Name = vars["user"]
|
||||
admin, name := CheckUser(r)
|
||||
if !admin {
|
||||
guest.Name = name
|
||||
}
|
||||
|
||||
libol.Info("ZTrust.DelGuest %s@%s", guest.Name, id)
|
||||
if err := ztrust.DelGuest(guest.Name, guest.Address); err == nil {
|
||||
ResponseJson(w, "success")
|
||||
@@ -144,9 +173,14 @@ func (h ZTrust) ListKnock(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
name := vars["user"]
|
||||
user := vars["user"]
|
||||
admin, name := CheckUser(r)
|
||||
if !admin {
|
||||
user = name
|
||||
}
|
||||
|
||||
rules := make([]schema.KnockRule, 0, 1024)
|
||||
ztrust.ListKnock(name, func(obj schema.KnockRule) {
|
||||
ztrust.ListKnock(user, func(obj schema.KnockRule) {
|
||||
rules = append(rules, obj)
|
||||
})
|
||||
|
||||
@@ -173,10 +207,15 @@ func (h ZTrust) AddKnock(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
name := vars["user"]
|
||||
libol.Info("ZTrust.AddKnock %s@%s", rule.Name, id)
|
||||
|
||||
if err := ztrust.Knock(name, rule.Protocol, rule.Dest, rule.Port, rule.Age); err == nil {
|
||||
user := vars["user"]
|
||||
admin, name := CheckUser(r)
|
||||
if !admin {
|
||||
user = name
|
||||
}
|
||||
libol.Info("ZTrust.AddKnock %s@%s", user, id)
|
||||
|
||||
if err := ztrust.Knock(user, rule.Protocol, rule.Dest, rule.Port, rule.Age); err == nil {
|
||||
ResponseJson(w, "success")
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
|
Reference in New Issue
Block a user