mirror of
https://github.com/juanfont/headscale.git
synced 2025-09-25 17:51:11 +02:00
[ASSIGN CUSTOM IP] register new machine with custom IPv4 address
This commit is contained in:
parent
fb203a2e45
commit
5cdc6bfcbe
@ -30,7 +30,7 @@ func init() {
|
|||||||
nodeCmd.AddCommand(listNodesCmd)
|
nodeCmd.AddCommand(listNodesCmd)
|
||||||
|
|
||||||
registerNodeCmd.Flags().StringP("user", "u", "", "User")
|
registerNodeCmd.Flags().StringP("user", "u", "", "User")
|
||||||
|
registerNodeCmd.Flags().StringP("ip", "p", "", "Ip")
|
||||||
registerNodeCmd.Flags().StringP("namespace", "n", "", "User")
|
registerNodeCmd.Flags().StringP("namespace", "n", "", "User")
|
||||||
registerNodeNamespaceFlag := registerNodeCmd.Flags().Lookup("namespace")
|
registerNodeNamespaceFlag := registerNodeCmd.Flags().Lookup("namespace")
|
||||||
registerNodeNamespaceFlag.Deprecated = deprecateNamespaceMessage
|
registerNodeNamespaceFlag.Deprecated = deprecateNamespaceMessage
|
||||||
@ -132,9 +132,19 @@ var registerNodeCmd = &cobra.Command{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ip, err := cmd.Flags().GetString("ip")
|
||||||
|
if err != nil {
|
||||||
|
ErrorOutput(
|
||||||
|
err,
|
||||||
|
fmt.Sprintf("Error getting node ip from flag: %s", err),
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
request := &v1.RegisterMachineRequest{
|
request := &v1.RegisterMachineRequest{
|
||||||
Key: machineKey,
|
Key: machineKey,
|
||||||
User: user,
|
User: user,
|
||||||
|
Ip: ip,
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := client.RegisterMachine(ctx, request)
|
response, err := client.RegisterMachine(ctx, request)
|
||||||
|
@ -127,6 +127,12 @@ docker exec headscale \
|
|||||||
headscale --user myfirstuser nodes register --key <YOU_+MACHINE_KEY>
|
headscale --user myfirstuser nodes register --key <YOU_+MACHINE_KEY>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Optionally use the --ip flag to assign a custom IPv4 address to your machine:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker exec headscale \
|
||||||
|
headscale --user myfirstuser nodes register --ip <YOUR_CUSTOM_IP> --key <YOU_+MACHINE_KEY>
|
||||||
|
```
|
||||||
### Register machine using a pre authenticated key
|
### Register machine using a pre authenticated key
|
||||||
|
|
||||||
Generate a key using the command line:
|
Generate a key using the command line:
|
||||||
|
@ -102,6 +102,12 @@ Register the machine:
|
|||||||
headscale --user myfirstuser nodes register --key <YOUR_MACHINE_KEY>
|
headscale --user myfirstuser nodes register --key <YOUR_MACHINE_KEY>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Optionally use the --ip flag to assign a custom IPv4 address to your machine:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
headscale --user myfirstuser nodes register --ip <YOUR_CUSTOM_IP> --key <YOUR_MACHINE_KEY>
|
||||||
|
```
|
||||||
|
|
||||||
### Register machine using a pre authenticated key
|
### Register machine using a pre authenticated key
|
||||||
|
|
||||||
Generate a key using the command line:
|
Generate a key using the command line:
|
||||||
|
@ -79,6 +79,12 @@ Register the machine:
|
|||||||
headscale --user myfirstuser nodes register --key <YOUR_MACHINE_KEY>
|
headscale --user myfirstuser nodes register --key <YOUR_MACHINE_KEY>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Optionally use the --ip flag to assign a custom IPv4 address to your machine:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
headscale --user myfirstuser nodes register --ip <YOUR_CUSTOM_IP> --key <YOUR_MACHINE_KEY>
|
||||||
|
```
|
||||||
|
|
||||||
### Register machine using a pre authenticated key
|
### Register machine using a pre authenticated key
|
||||||
|
|
||||||
Generate a key using the command line:
|
Generate a key using the command line:
|
||||||
|
@ -139,6 +139,12 @@ Register the machine:
|
|||||||
headscale --user myfirstuser nodes register --key <YOU_+MACHINE_KEY>
|
headscale --user myfirstuser nodes register --key <YOU_+MACHINE_KEY>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Optionally use the --ip flag to assign a custom IPv4 address to your machine:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
headscale --user myfirstuser nodes register --ip <YOUR_CUSTOM_IP> --key <YOUR_MACHINE_KEY>
|
||||||
|
```
|
||||||
|
|
||||||
### Register machine using a pre authenticated key
|
### Register machine using a pre authenticated key
|
||||||
|
|
||||||
Generate a key using the command line:
|
Generate a key using the command line:
|
||||||
|
@ -368,6 +368,7 @@ func (h *Headscale) handleAuthKey(
|
|||||||
|
|
||||||
machine, err = h.db.RegisterMachine(
|
machine, err = h.db.RegisterMachine(
|
||||||
machineToRegister,
|
machineToRegister,
|
||||||
|
"",
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().
|
||||||
|
@ -17,6 +17,24 @@ import (
|
|||||||
|
|
||||||
var ErrCouldNotAllocateIP = errors.New("could not find any suitable IP")
|
var ErrCouldNotAllocateIP = errors.New("could not find any suitable IP")
|
||||||
|
|
||||||
|
func (hsdb *HSDatabase) isInRange(address netip.Addr) (bool, error) {
|
||||||
|
counter := 0
|
||||||
|
for _, ipPrefix := range hsdb.ipPrefixes {
|
||||||
|
ipPrefixNetworkAddress, ipPrefixBroadcastAddress := util.GetIPPrefixEndpoints(ipPrefix)
|
||||||
|
|
||||||
|
if ipPrefixNetworkAddress.Compare(address) == -1 &&
|
||||||
|
ipPrefixBroadcastAddress.Compare(address) == 1 {
|
||||||
|
counter += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if counter > 0 {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, ErrRequestedIPNotInPrefixRange
|
||||||
|
}
|
||||||
|
|
||||||
func (hsdb *HSDatabase) getAvailableIPs() (types.MachineAddresses, error) {
|
func (hsdb *HSDatabase) getAvailableIPs() (types.MachineAddresses, error) {
|
||||||
var ips types.MachineAddresses
|
var ips types.MachineAddresses
|
||||||
var err error
|
var err error
|
||||||
|
@ -31,6 +31,7 @@ var (
|
|||||||
ErrDifferentRegisteredUser = errors.New(
|
ErrDifferentRegisteredUser = errors.New(
|
||||||
"machine was previously registered with a different user",
|
"machine was previously registered with a different user",
|
||||||
)
|
)
|
||||||
|
ErrRequestedIPNotInPrefixRange = errors.New("the ip you provided is not in the configured prefix range")
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListPeers returns all peers of machine, regardless of any Policy or if the node is expired.
|
// ListPeers returns all peers of machine, regardless of any Policy or if the node is expired.
|
||||||
@ -355,6 +356,7 @@ func (hsdb *HSDatabase) RegisterMachineFromAuthCallback(
|
|||||||
userName string,
|
userName string,
|
||||||
machineExpiry *time.Time,
|
machineExpiry *time.Time,
|
||||||
registrationMethod string,
|
registrationMethod string,
|
||||||
|
requestedIP string,
|
||||||
) (*types.Machine, error) {
|
) (*types.Machine, error) {
|
||||||
nodeKey := key.NodePublic{}
|
nodeKey := key.NodePublic{}
|
||||||
err := nodeKey.UnmarshalText([]byte(nodeKeyStr))
|
err := nodeKey.UnmarshalText([]byte(nodeKeyStr))
|
||||||
@ -365,6 +367,7 @@ func (hsdb *HSDatabase) RegisterMachineFromAuthCallback(
|
|||||||
log.Debug().
|
log.Debug().
|
||||||
Str("nodeKey", nodeKey.ShortString()).
|
Str("nodeKey", nodeKey.ShortString()).
|
||||||
Str("userName", userName).
|
Str("userName", userName).
|
||||||
|
Str("requestedIp", requestedIP).
|
||||||
Str("registrationMethod", registrationMethod).
|
Str("registrationMethod", registrationMethod).
|
||||||
Str("expiresAt", fmt.Sprintf("%v", machineExpiry)).
|
Str("expiresAt", fmt.Sprintf("%v", machineExpiry)).
|
||||||
Msg("Registering machine from API/CLI or auth callback")
|
Msg("Registering machine from API/CLI or auth callback")
|
||||||
@ -394,6 +397,7 @@ func (hsdb *HSDatabase) RegisterMachineFromAuthCallback(
|
|||||||
|
|
||||||
machine, err := hsdb.RegisterMachine(
|
machine, err := hsdb.RegisterMachine(
|
||||||
registrationMachine,
|
registrationMachine,
|
||||||
|
requestedIP,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -410,13 +414,14 @@ func (hsdb *HSDatabase) RegisterMachineFromAuthCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey.
|
// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey.
|
||||||
func (hsdb *HSDatabase) RegisterMachine(machine types.Machine,
|
func (hsdb *HSDatabase) RegisterMachine(machine types.Machine, requestedIP string,
|
||||||
) (*types.Machine, error) {
|
) (*types.Machine, error) {
|
||||||
log.Debug().
|
log.Debug().
|
||||||
Str("machine", machine.Hostname).
|
Str("machine", machine.Hostname).
|
||||||
Str("machine_key", machine.MachineKey).
|
Str("machine_key", machine.MachineKey).
|
||||||
Str("node_key", machine.NodeKey).
|
Str("node_key", machine.NodeKey).
|
||||||
Str("user", machine.User.Name).
|
Str("user", machine.User.Name).
|
||||||
|
Str("requestedIp", requestedIP).
|
||||||
Msg("Registering machine")
|
Msg("Registering machine")
|
||||||
|
|
||||||
// If the machine exists and we had already IPs for it, we just save it
|
// If the machine exists and we had already IPs for it, we just save it
|
||||||
@ -452,7 +457,42 @@ func (hsdb *HSDatabase) RegisterMachine(machine types.Machine,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
machine.IPAddresses = ips
|
if requestedIP != "" {
|
||||||
|
parsedip, err := netip.ParseAddr(requestedIP)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
inrange, err := hsdb.isInRange(parsedip)
|
||||||
|
if !inrange {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
usedIps, err := hsdb.getUsedIPs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var staticip types.MachineAddresses
|
||||||
|
if !usedIps.Contains(parsedip) {
|
||||||
|
// avaliableipv6, err := netip.ParseAddr(ips.StringSlice()[1])
|
||||||
|
// if ips[1].Is4() {
|
||||||
|
// avaliableipv6, err = netip.ParseAddr(ips.StringSlice()[0])
|
||||||
|
//}
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
//}
|
||||||
|
|
||||||
|
staticip = append(staticip, parsedip)
|
||||||
|
|
||||||
|
machine.IPAddresses = staticip
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
machine.IPAddresses = ips
|
||||||
|
}
|
||||||
|
|
||||||
if err := hsdb.db.Save(&machine).Error; err != nil {
|
if err := hsdb.db.Save(&machine).Error; err != nil {
|
||||||
return nil, fmt.Errorf("failed register(save) machine in the database: %w", err)
|
return nil, fmt.Errorf("failed register(save) machine in the database: %w", err)
|
||||||
@ -461,7 +501,7 @@ func (hsdb *HSDatabase) RegisterMachine(machine types.Machine,
|
|||||||
log.Trace().
|
log.Trace().
|
||||||
Caller().
|
Caller().
|
||||||
Str("machine", machine.Hostname).
|
Str("machine", machine.Hostname).
|
||||||
Str("ip", strings.Join(ips.StringSlice(), ",")).
|
Str("ip", strings.Join(machine.IPAddresses.StringSlice(), ",")).
|
||||||
Msg("Machine registered with the database")
|
Msg("Machine registered with the database")
|
||||||
|
|
||||||
return &machine, nil
|
return &machine, nil
|
||||||
|
@ -173,6 +173,7 @@ func (api headscaleV1APIServer) RegisterMachine(
|
|||||||
log.Trace().
|
log.Trace().
|
||||||
Str("user", request.GetUser()).
|
Str("user", request.GetUser()).
|
||||||
Str("node_key", request.GetKey()).
|
Str("node_key", request.GetKey()).
|
||||||
|
Str("ip", request.GetIp()).
|
||||||
Msg("Registering machine")
|
Msg("Registering machine")
|
||||||
|
|
||||||
machine, err := api.h.db.RegisterMachineFromAuthCallback(
|
machine, err := api.h.db.RegisterMachineFromAuthCallback(
|
||||||
@ -181,6 +182,7 @@ func (api headscaleV1APIServer) RegisterMachine(
|
|||||||
request.GetUser(),
|
request.GetUser(),
|
||||||
nil,
|
nil,
|
||||||
util.RegisterMethodCLI,
|
util.RegisterMethodCLI,
|
||||||
|
request.GetIp(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -651,6 +651,7 @@ func (h *Headscale) registerMachineForOIDCCallback(
|
|||||||
user.Name,
|
user.Name,
|
||||||
&expiry,
|
&expiry,
|
||||||
util.RegisterMethodOIDC,
|
util.RegisterMethodOIDC,
|
||||||
|
"",
|
||||||
); err != nil {
|
); err != nil {
|
||||||
util.LogErr(err, "could not register machine")
|
util.LogErr(err, "could not register machine")
|
||||||
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
writer.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
@ -50,6 +50,7 @@ message Machine {
|
|||||||
message RegisterMachineRequest {
|
message RegisterMachineRequest {
|
||||||
string user = 1;
|
string user = 1;
|
||||||
string key = 2;
|
string key = 2;
|
||||||
|
string ip = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message RegisterMachineResponse {
|
message RegisterMachineResponse {
|
||||||
|
Loading…
Reference in New Issue
Block a user