Skip to content

Commit

Permalink
Merge branch 'release/3.18.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
keliramu committed May 13, 2024
2 parents 43ade03 + 3fc9543 commit 9b6e179
Show file tree
Hide file tree
Showing 21 changed files with 451 additions and 325 deletions.
2 changes: 0 additions & 2 deletions .golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ linters:
- gosimple
- govet
#- ineffassign
- interfacer
#- lll
- misspell
#- nakedret
Expand All @@ -36,5 +35,4 @@ linters:
- unconvert
- unparam
- unused
- varcheck
- whitespace
9 changes: 4 additions & 5 deletions cli/cli_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ func Status(resp *pb.StatusResponse) string {
var b strings.Builder
b.WriteString(fmt.Sprintf("Status: %s\n", resp.State))

hostname := resp.Name
if hostname == "" {
hostname = resp.Hostname
if resp.Name != "" {
b.WriteString(fmt.Sprintf("Server: %s\n", resp.Name))
}

if hostname != "" {
b.WriteString(fmt.Sprintf("Hostname: %s\n", hostname))
if resp.Hostname != "" {
b.WriteString(fmt.Sprintf("Hostname: %s\n", resp.Hostname))
}

if resp.Ip != "" {
Expand Down
2 changes: 2 additions & 0 deletions cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/NordSecurity/nordvpn-linux/daemon/pb"
"github.com/NordSecurity/nordvpn-linux/daemon/response"
"github.com/NordSecurity/nordvpn-linux/daemon/routes"
"github.com/NordSecurity/nordvpn-linux/daemon/routes/ifgroup"
"github.com/NordSecurity/nordvpn-linux/daemon/routes/iprouter"
"github.com/NordSecurity/nordvpn-linux/daemon/routes/iprule"
"github.com/NordSecurity/nordvpn-linux/daemon/routes/norouter"
Expand Down Expand Up @@ -361,6 +362,7 @@ func main() {
&norule.Facade{},
iprule.NewRouter(
routes.NewSysctlRPFilterManager(),
ifgroup.NewNetlinkManager(device.ListPhysical),
cfg.FirewallMark,
),
cfg.Routing.Get(),
Expand Down
2 changes: 2 additions & 0 deletions contrib/changelog/prod/3.18.0_1713364856.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Introducing our latest companion - the notification tray. This handy addition will give you real-time updates on your VPN connection status.
* Fixed: We've gotten rid of the bug that prevented Kill Switch from disabling internet access for Meshnet peers routing traffic through your device. Now when your VPN connection drops and Kill Switch is enabled, it securely blocks internet access for these connections.
1 change: 1 addition & 0 deletions contrib/changelog/prod/3.18.1_1715337996.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* We've addressed potential security vulnerabilities in this release. Update now for the safest version.
118 changes: 118 additions & 0 deletions daemon/routes/ifgroup/ifgroup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package ifgroup

import (
"errors"
"fmt"
"net"
"sync"

"github.com/vishvananda/netlink"
)

// Group is a group to be used within the application while it works
const Group = 0xe1f1

var (
// ErrAlreadySet defines that NetlinkManager is already set.
ErrAlreadySet = errors.New("already set")
// ErrNotSet defines that NetlinkManager is not set yet.
ErrNotSet = errors.New("not set")
)

// Manager is responsible for managing groups of network interfaces
type Manager interface {
Set() error
Unset() error
}

// NetlinkManager is responsible for setting ifgroup to all of the network interfaces given
// by a deviceList function and reverting the changes when needed.
type NetlinkManager struct {
group int
deviceList func() ([]net.Interface, error)
set bool
backup map[int]uint32
mu sync.Mutex
}

// NewNetlinkManager is a default constructor for NetlinkManager
func NewNetlinkManager(deviceList func() ([]net.Interface, error)) *NetlinkManager {
return &NetlinkManager{
group: Group,
deviceList: deviceList,
backup: map[int]uint32{},
}
}

// Set sets the ifgroup for all of the network interfaces given by deviceList and stores their
// group IDs as a backup to be used for unset.
func (s *NetlinkManager) Set() error {
s.mu.Lock()
defer s.mu.Unlock()

if s.set {
return ErrAlreadySet
}

devices, err := s.deviceList()
if err != nil {
return fmt.Errorf("listing devices: %w", err)
}

netlinkDevices := make([]netlink.Link, len(devices))

// Save old group values for reverting the changes
for i, device := range devices {
link, err := netlink.LinkByIndex(device.Index)
if err != nil {
return fmt.Errorf("retrieving netlink device '%d': %w", device.Index, err)
}
netlinkDevices[i] = link
var group uint32 = 0
if attrs := link.Attrs(); attrs != nil {
group = attrs.Group
}
s.backup[device.Index] = group
}

// Set the new group for all of the given devices
for _, device := range netlinkDevices {
if err := netlink.LinkSetGroup(device, s.group); err != nil {
return fmt.Errorf("setting group for netlink device: %w", err)
}
}

s.set = true
return nil
}

func (s *NetlinkManager) Unset() error {
s.mu.Lock()
defer s.mu.Unlock()
if !s.set {
return ErrNotSet
}
devices, err := s.deviceList()
if err != nil {
return fmt.Errorf("lilsting devices: %w", err)
}

for _, device := range devices {
link, err := netlink.LinkByIndex(device.Index)
if err != nil {
return fmt.Errorf("retrieving netlink device '%d': %w", device.Index, err)
}
var group uint32 = 0
backup, ok := s.backup[device.Index]
if ok {
group = backup
}
if err := netlink.LinkSetGroup(link, int(group)); err != nil {
return fmt.Errorf("setting group for netlink device: %w", err)
}
}

s.backup = make(map[int]uint32)
s.set = false
return nil
}
63 changes: 63 additions & 0 deletions daemon/routes/ifgroup/ifgroup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package ifgroup

import (
"testing"

"github.com/NordSecurity/nordvpn-linux/daemon/device"
"github.com/NordSecurity/nordvpn-linux/test/category"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/vishvananda/netlink"
)

func TestNetlinkManager_SetUnset(t *testing.T) {
category.Set(t, category.Link)

devices, err := device.ListPhysical()
require.NoError(t, err)
require.Greater(t, len(devices), 0)

groups := map[int]uint32{}

// Save the groups before set
for _, d := range devices {
link, err := netlink.LinkByIndex(d.Index)
require.NoError(t, err)
var group uint32 = 0
attrs := link.Attrs()
if attrs != nil {
group = attrs.Group
}
groups[d.Index] = group
}

// Set the groups
manager := NewNetlinkManager(device.ListPhysical)
assert.NoError(t, manager.Set())

// Check if set happened correctly
for _, d := range devices {
link, err := netlink.LinkByIndex(d.Index)
assert.NoError(t, err)
attrs := link.Attrs()
assert.NotNil(t, attrs)
if attrs != nil {
assert.Equal(t, Group, attrs.Group)
}
}

// Unset groups
assert.NoError(t, manager.Unset())
assert.NoError(t, manager.Set())

// Check if unset happened correctly
for _, d := range devices {
link, err := netlink.LinkByIndex(d.Index)
assert.NoError(t, err)
attrs := link.Attrs()
assert.NotNil(t, attrs)
if attrs != nil {
assert.Equal(t, groups[d.Index], attrs.Group)
}
}
}

0 comments on commit 9b6e179

Please sign in to comment.