github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/supervisor/daemon/wireguard/wginterface/interface.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package wginterface 19 20 import ( 21 "bufio" 22 "fmt" 23 "net" 24 "strings" 25 26 "github.com/rs/zerolog/log" 27 "golang.zx2c4.com/wireguard/conn" 28 "golang.zx2c4.com/wireguard/device" 29 30 "github.com/mysteriumnetwork/node/services/wireguard/connection/dns" 31 "github.com/mysteriumnetwork/node/services/wireguard/wgcfg" 32 "github.com/mysteriumnetwork/node/utils/netutil" 33 ) 34 35 // WgInterface represents WireGuard tunnel with underlying device. 36 type WgInterface struct { 37 Name string 38 Device *device.Device 39 uapi net.Listener 40 dnsManager dns.Manager 41 } 42 43 // New creates new WgInterface instance. 44 func New(cfg wgcfg.DeviceConfig, uid string) (*WgInterface, error) { 45 tunnel, interfaceName, err := createTunnel(cfg.IfaceName, cfg.DNS) 46 if err != nil { 47 return nil, fmt.Errorf("failed to create TUN device %s: %w", cfg.IfaceName, err) 48 } 49 50 logger := device.NewLogger(device.LogLevelVerbose, fmt.Sprintf("(%s) ", interfaceName)) 51 logger.Verbosef("Starting wireguard-go") 52 53 logger.Verbosef("Starting device") 54 wgDevice := device.NewDevice(tunnel, conn.NewDefaultBind(), logger) 55 56 log.Info().Msg("Creating UAPI listener") 57 uapi, err := newUAPIListener(interfaceName) 58 if err != nil { 59 return nil, fmt.Errorf("failed to listen on UAPI socket: %w", err) 60 } 61 62 log.Info().Msg("Applying interface configuration") 63 if err := wgDevice.IpcSetOperation(bufio.NewReader(strings.NewReader(cfg.Encode()))); err != nil { 64 down(uapi, wgDevice, nil) 65 return nil, fmt.Errorf("could not set device uapi config: %w", err) 66 } 67 68 log.Info().Msg("Bringing device up") 69 wgDevice.Up() 70 71 log.Info().Msg("Configuring network") 72 dnsManager := dns.NewManager() 73 if err := configureNetwork(cfg, dnsManager); err != nil { 74 down(uapi, wgDevice, dnsManager) 75 return nil, fmt.Errorf("could not setup network: %w", err) 76 } 77 78 if err := applySocketPermissions(interfaceName, uid); err != nil { 79 down(uapi, wgDevice, dnsManager) 80 return nil, fmt.Errorf("could not apply socket permissions: %w", err) 81 } 82 83 wgInterface := &WgInterface{ 84 Name: interfaceName, 85 Device: wgDevice, 86 uapi: uapi, 87 dnsManager: dnsManager, 88 } 89 log.Info().Msg("Accepting UAPI requests") 90 go wgInterface.accept() 91 92 return wgInterface, nil 93 } 94 95 // Reconfigure applies new configuration for the existing wireguard interface. 96 func (a *WgInterface) Reconfigure(cfg wgcfg.DeviceConfig) error { 97 log.Info().Msgf("Applying interface configuration") 98 if err := a.Device.IpcSetOperation(bufio.NewReader(strings.NewReader(cfg.Encode()))); err != nil { 99 return fmt.Errorf("could not set device uapi config: %w", err) 100 } 101 102 log.Info().Msg("Bringing device up") 103 a.Device.Up() 104 105 log.Info().Msg("Configuring network") 106 dnsManager := dns.NewManager() 107 if err := configureNetwork(cfg, dnsManager); err != nil { 108 return fmt.Errorf("could not setup network: %w", err) 109 } 110 111 return nil 112 } 113 114 // Accept listens for WireGuard configuration changes via user space socket. 115 func (a *WgInterface) accept() { 116 for { 117 conn, err := a.uapi.Accept() 118 if err != nil { 119 log.Err(err).Msg("Failed to close UAPI listener") 120 return 121 } 122 go a.Device.IpcHandle(conn) 123 } 124 } 125 126 func down(uapi net.Listener, d *device.Device, dnsManager dns.Manager) { 127 if uapi != nil { 128 if err := uapi.Close(); err != nil { 129 log.Warn().Err(err).Msg("Could not close uapi socket") 130 } 131 } 132 if d != nil { 133 d.Close() 134 } 135 136 disableFirewall() 137 138 if dnsManager != nil { 139 if err := dnsManager.Clean(); err != nil { 140 log.Err(err).Msg("Could not clean DNS") 141 } 142 } 143 } 144 145 // Down closes device and user space api socket. 146 func (a *WgInterface) Down() { 147 down(a.uapi, a.Device, a.dnsManager) 148 } 149 150 func configureNetwork(cfg wgcfg.DeviceConfig, dnsManager dns.Manager) error { 151 if err := netutil.AssignIP(cfg.IfaceName, cfg.Subnet); err != nil { 152 return fmt.Errorf("failed to assign IP address: %w", err) 153 } 154 155 if cfg.Peer.Endpoint != nil { 156 if err := netutil.AddDefaultRoute(cfg.IfaceName); err != nil { 157 return fmt.Errorf("could not add default route for %s: %w", cfg.IfaceName, err) 158 } 159 } 160 161 if err := dnsManager.Set(dns.Config{ 162 ScriptDir: cfg.DNSScriptDir, 163 IfaceName: cfg.IfaceName, 164 DNS: cfg.DNS, 165 }); err != nil { 166 return fmt.Errorf("could not set DNS: %w", err) 167 } 168 169 return nil 170 }