Connecting to WireGuard VPN from Linux (2024)

Connecting to WireGuard VPN from Linux

Starting from KeeneticOS 3.3, it is possible to use aWireGuard VPNtunnel to remotely connect to the local network of the Keenetic router.

Important

If you plan to set up your Keenetic as a VPN server, make sure that it has apublic IP address, and if you useKeenDNS, that it works in 'Direct access' mode, which also requires a public IP address. If any of these conditions are not met, you will not connect to such a server from the Internet.

First, you need to configure the WireGuard server on the Keenetic device. The following instruction shows the process:Configuring a WireGuard VPN between two Keenetic routers. Then move on to the VPN client setup.

Here is an example of how to connect to the VPN server from a Linux operating system, using CLI (terminal) for setting up the connection inUbuntu 18.04 LTSand the graphical interface in theLinux Mint 19.3 LTSdistribution.

To establish a connection to a Keenetic WireGuard server on a Linux-based computer, you must install theWireGuardpackage using the built-inaptpackage manager.

Installation and configuration options in the terminal
  1. Launch theterminaland install the necessary packages needed for WireGuard to work in the terminal and configure the connection in NetworkManager GUI (a program for managing network connections): application package, kernel module, kernel header files.

    [my@my-wrk-lnv ~]$ sudo apt install wireguardReading package lists... DoneBuilding dependency tree... DoneReading state information... DoneThe following additional packages will be installed: wireguard-toolsSuggested packages: openresolv | resolvconfThe following NEW packages will be installed: wireguard wireguard-tools0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.Need to get 90,0 kB of archives.After this operation, 344 kB of additional disk space will be used.Do you want to continue? [Y/n] yGet:1 http://mirrors.daticum.com/ubuntu impish/universe amd64 wireguard-tools amd64 1.0.20210424-1ubuntu1 [86,9 kB]Get:2 http://mirrors.daticum.com/ubuntu impish/universe amd64 wireguard all 1.0.20210424-1ubuntu1 [3 126 B]Fetched 90,0 kB in 0s (1 181 kB/s)Selecting previously unselected package wireguard-tools.(Reading database ... 234329 files and directories currently installed.)Preparing to unpack .../wireguard-tools_1.0.20210424-1ubuntu1_amd64.deb ...Unpacking wireguard-tools (1.0.20210424-1ubuntu1) ...Selecting previously unselected package wireguard.Preparing to unpack .../wireguard_1.0.20210424-1ubuntu1_all.deb ...Unpacking wireguard (1.0.20210424-1ubuntu1) ...Setting up wireguard-tools (1.0.20210424-1ubuntu1) ...wg-quick.target is a disabled or a static unit not running, not starting it.Setting up wireguard (1.0.20210424-1ubuntu1) ...Processing triggers for man-db (2.9.4-2) ...
  2. Create a Private Key and a Public Key:

    [my@my-wrk-lnv ~]$ cd /etc/wireguard/[my@my-wrk-lnv wireguard]$ umask 077[my@my-wrk-lnv wireguard]$ sudo -i[sudo] password for my:root@my-wrk-lnv:~# cd /etc/wireguard/root@my-wrk-lnv:/etc/wireguard# wg genkey > private-keyroot@my-wrk-lnv:/etc/wireguard# wg pubkey > public-key < private-keyroot@my-wrk-lnv:~# exit[my@my-wrk-lnv wireguard]$ sudo cat private-key AOSXWm+sXxRuu/Uo8lysE4PIwVZTRDD+YV6w3HicGHg=[my@my-wrk-lnv wireguard]$ sudo cat public-key xxKBcZlhZlbjW7yFuhZ08l294HBAp2I/iM05YE8vs0Y=[my@my-wrk-lnv wireguard]$ cd -[my@my-wrk-lnv ~]$

    Important

    If you get the 'Permission denied' result after typingcd /etc/wireguard/, you do not have root access to read the directory.

    [my@my-wrk-lnv ~]$ cd /etc/wireguard/bash: cd: /etc/wireguard/: Permission denied

    Change the owner, who can access the directory without root access rights:

    [my@my-wrk-lnv ~]$ sudo chown -R my /etc/wireguard/[my@my-wrk-lnv ~]$ cd /etc/wireguard[my@my-wrk-lnv wireguard]$

    After configuring the connection, you can change back the owner for access to the default directory:

    [my@my-wrk-lnv wireguard]$ cd - /home/my[my@my-wrk-lnv ~]$ sudo chown -R root /etc/wireguard/
  3. Create thewg-client.confconfiguration file:

    [my@my-wrk-lnv wireguard]$ sudo touch wg-client.conf[my@my-wrk-lnv wireguard]$ ls -1private-keypublic-keywg-client.conf
  4. Let's add the connection settings to the created configuration filewg-client.confby opening the file with a text editor, for example,nano:

    [my@my-wrk-lnv wireguard]$ sudo nano wg-client.conf[sudo] password for my:[Interface]PrivateKey = AOSXWm+sXxRuu/Uo8lysE4PIwVZTRDD+YV6w3HicGHg=Address = 172.16.82.5/24DNS =[Peer]PublicKey = 1YVx+x3C817V9YdhUtpUhzyDLVj5tnK2m//WjFGynm4=AllowedIPs = 172.16.82.1/32, 192.168.22.0/24Endpoint = wgwrkserver.dynns.com:16631PersistentKeepalive = 5
    [my@my-wrk-lnv wireguard]$ sudo nano wg-client.conf[sudo] пароль для my:[Interface]PrivateKey = AOSXWm+sXxRuu/Uo8lysE4PIwVZTRDD+YV6w3HicGHg=Address = 172.16.82.5/24DNS =[Peer]PublicKey = 1YVx+x3C817V9YdhUtpUhzyDLVj5tnK2m//WjFGynm4=AllowedIPs = 172.16.82.1/32, 192.168.22.0/24Endpoint = wgwrkserver.dynns.com:16631PersistentKeepalive = 5

    Configuring client's [Interface]:

    In the client interface's 'PrivateKey' field, enter the private key created in step 2.

    The key can be viewed with thecatcommand:

    [my@my-wrk-lnv wireguard]$ sudo cat private-keyAOSXWm+sXxRuu/Uo8lysE4PIwVZTRDD+YV6w3HicGHg=

    In the 'Addresses' field of the client interface, specify the IP address in IP/bitmask format — 172.16.82.5/24 (this is the internal address of the tunnel). Another subnet can be used, but it must be chosen from aprivate address rangeand avoid overlap with other subnets configured on these devices.

    Important

    If you haveInternet access through a WireGuard VPN tunnelconfigured on the [Interface] side of the client, you must specify the DNS server in the 'DNS=' field.

    In our example, the address of the DNS server from Google 8.8.8.8:

    [Interface]PrivateKey =AOSXWm+sXxRuu/Uo8lysE4PIwVZTRDD+YV6w3HicGHg=Address = 172.16.82.5/24DNS = 8.8.8.8[Peer]PublicKey = 1YVx+x3C817V9YdhUtpUhzyDLVj5tnK2m//WjFGynm4=AllowedIPs = 172.16.82.1/32, 192.168.22.0/24Endpoint = enpwgwrkserver.dynns.com:16631PersistentKeepalive = 5

    Configuring the server's [Peer]:

    In the 'Public key' field, insert the public key of the server, which can be copied to the clipboard from the WireGuard settings in the router's web interface:

    Connecting to WireGuard VPN from Linux (1)

    In the 'AllowedIPs' field, enter allowed IP addresses in IP/bitmask format — 172.16.82.1/32 (the internal server address) and 192.168.22.0/24 (address of the local segment of the Keenetic router).

    In the 'Endpoint' field, enter the public IP address or domain name of the WireGuard server and the listening port on which the WireGuard client will establish communication.

    In the 'PersistentKeepalive' field, enter the frequency of attempts to check the availability of the remote side of the connection. Usually, a 3-5 second interval between checks is enough.

  5. Set up a remote connection on the side of the previously configuredWireGuard server.

    Connect to the router'sweb interfaceand go to the 'Other connections' page in the 'Internet' menu. Click on the previously created WireGuard connection ('wg-keenetic-server') and add the peer's settings. Click on 'Add peer' to open the peer settings window, in which you specify the name of the tunnel 'wg-ubuntu-home'.

    In the 'Public key' field, insert the key created in step 2.

    As a reminder, the key can be viewed with thecatcommand:

    [my@my-wrk-lnv wireguard]$ sudo cat public-keyxxKBcZlhZlbjW7yFuhZ08l294HBAp2I/iM05YE8vs0Y=

    In the 'Allowed IPs' field, specify the address from which traffic will be allowed to the server in IP/bitmask format — 172.16.82.5/32

    In the 'Persistent keepalive' field, you must specify the frequency of attempts to check the availability of the remote side of the connection. Usually, a 10-15 second interval between checks is enough. The default value of the 'Persistent keepalive' in the Keenetic peer settings is 30 seconds.

    Click 'Save'.

    Connecting to WireGuard VPN from Linux (2)

  6. Create an automatic WireGuard connection at OS startup via the Systemd initialization system, which allows you to start and manage Linux system daemons:

    [my@my-wrk-lnv ~]$ sudo systemctl enable wg-quick@wg-client.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg-client.service → /lib/systemd/system/wg-quick@.service.

    Important

    In the service name***.serviceenter the configuration namewg-client.conf

  7. Start the WireGuard connection:

    [my@my-wrk-lnv ~]$ sudo systemctl start wg-quick@wg-client.service

    Important

    If the service does not start, you should check the boot log with the commandsystemctl status wg-quick@wg-client.serviceorjournalctl -xe:

    [my@my-wrk-lnv ~]$ systemctl status wg-quick@wg-client.servicewg-quick@wg-client.service - WireGuard via wg-quick(8) for wg/clientLoaded: loaded (/lib/systemd/system/wg-quick@.service; indirect; vendor preset: enabled)Active: failed (Result: exit-code) since Wed 2020-04-22 19:55:59 MSK; 8s agoDocs: man:wg-quick(8)\man:wg(8)https://www.wireguard.com/https://www.wireguard.com/quickstart/https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8Process: 8734 ExecStart=/usr/bin/wg-quick up wg-client (code=exited, status=127)Main PID: 8734 (code=exited, status=127)apr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] ip link add wg-client type wireguardapr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] wg setconf wg-client /dev/fd/63apr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] ip -4 address add 172.16.82.20/24 dev wg-clientapr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] ip link set mtu 1420 up dev wg-clientapr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] resolvconf -a wg-client -m 0 -xapr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: /usr/bin/wg-quick: line 31: resolvconf: command not foundapr 22 19:55:59 my@my-wrk-lnv wg-quick[8734]: [#] ip link delete dev wg-clientapr 22 19:55:59 my@my-wrk-lnv systemd[1]: wg-quick@wg-client.service: Main process exited, code=exited, status=127/n/aapr 22 19:55:59 my@my-wrk-lnv systemd[1]: wg-quick@wg-client.service: Failed with result 'exit-code'.apr 22 19:55:59 my@my-wrk-lnv systemd[1]: Failed to start WireGuard via wg-quick(8) for wg/client.

    According to the error, there is no installed packageresolvconf, which is necessary forwg-quick, install the package:

    [my@my-wrk-lnv ~]$ sudo apt install resolvconfReading package lists... DoneBuilding dependency tree... DoneReading state information... DoneThe following NEW packages will be installed: resolvconf0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.Need to get 54,7 kB of archives.After this operation, 203 kB of additional disk space will be used.Get:1 http://mirrors.daticum.com/ubuntu impish/universe amd64 resolvconf all 1.84ubuntu1 [54,7 kB]Fetched 54,7 kB in 0s (888 kB/s)Preconfiguring packages ...Selecting previously unselected package resolvconf.(Reading database ... 234409 files and directories currently installed.)Preparing to unpack .../resolvconf_1.84ubuntu1_all.deb ...Unpacking resolvconf (1.84ubuntu1) ...Setting up resolvconf (1.84ubuntu1) ...Created symlink /etc/systemd/system/sysinit.target.wants/resolvconf.service → /lib/systemd/system/resolvconf.service.Created symlink /etc/systemd/system/systemd-resolved.service.wants/resolvconf-pull-resolved.path → /lib/systemd/system/resolvconf-pull-resolved.path.Created symlink /etc/systemd/system/systemd-resolved.service.wants/resolvconf-pull-resolved.service → /lib/systemd/system/resolvconf-pull-resolved.service.Processing triggers for ureadahead (0.100.0-21) ...Processing triggers for man-db (2.9.4-2) ...Processing triggers for resolvconf (1.84ubuntu1) ...

    After the package is installed, check that the service is running. Checking the connection:

    [my@my-wrk-lnv ~]$ sudo wginterface: wg-clientpublic key: xxKBcZlhZlbjW7yFuhZ08l294HBAp2I/iM05YE8vs0Y=private key: (hidden)listening port: 45757peer: 1YVx+x3C817V9YdhUtpUhzyDLVj5tnK2m//WjFGynm4=endpoint: 193.0.174.159:16631allowed ips: 172.16.82.1/32, 192.168.22.0/24transfer: 0 B received, 148 B sentpersistent keepalive: every 5 seconds

    To check the availability of the server, you can send ICMP packets to the IP address:

    [my@my-wrk-lnv ~]$ ping -c 10 -s 100 192.168.22.1PING 192.168.22.1 (192.168.22.1) 100(128) bytes of data.108 bytes from 192.168.22.1: icmp_seq=1 ttl=64 time=6.76 ms108 bytes from 192.168.22.1: icmp_seq=2 ttl=64 time=6.70 ms108 bytes from 192.168.22.1: icmp_seq=3 ttl=64 time=6.63 ms108 bytes from 192.168.22.1: icmp_seq=4 ttl=64 time=6.84 ms108 bytes from 192.168.22.1: icmp_seq=5 ttl=64 time=6.57 ms108 bytes from 192.168.22.1: icmp_seq=6 ttl=64 time=6.24 ms108 bytes from 192.168.22.1: icmp_seq=7 ttl=64 time=9.92 ms108 bytes from 192.168.22.1: icmp_seq=8 ttl=64 time=9.75 ms108 bytes from 192.168.22.1: icmp_seq=9 ttl=64 time=5.77 ms108 bytes from 192.168.22.1: icmp_seq=10 ttl=64 time=7.03 ms--- 192.168.22.1 ping statistics ---10 packets transmitted, 10 received, 0% packet loss, time 9014msrtt min/avg/max/mdev = 5.778/7.225/9.920/1.349 ms
  8. To disable WireGuard connection to start automatically at OS startup, via the Systemd initialization system, enter the following command:

    [my@my-wrk-lnv ~]$ sudo systemctl disable wg-quick@wg-client.serviceRemoved /etc/systemd/system/multi-user.target.wants/wg-quick@wg-client.service
  9. To stop the WireGuard connection, enter the following command:

    [my@my-wrk-lnv ~]$ sudo systemctl stop wg-quick@wg-client.service

    Setup completed.

Installation and configuration option with NetworkManager

NetworkManager GUI is a graphical shell for network connection management software.

Brief command sequence:

git clone https://github.com/max-moser/network-manager-wireguardcd network-manager-wireguard./autogen.sh --without-libnm-glib./configure --without-libnm-glib --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib/x86_64-linux-gnu --libexecdir=/usr/lib/NetworkManager --localstatedir=/varmakesudo make install

Important

If the plugin installation does not complete successfully or if there are not enough packages to install the plugin, run:

sudo apt install wireguard git dh-autoreconf libglib2.0-dev intltool build-essential libgtk-3-dev libnma-dev libsecret-1-dev network-manager-dev resolvconf

Detailed command sequence:

  1. Clone the plugin code from the Github repository:

    [my@my-wrk-lnv ~]$ git clone https://github.com/max-moser/network-manager-wireguardCloning into 'network-manager-wireguard'...remote: Enumerating objects: 534, done.remote: Total 534 (delta 0), reused 0 (delta 0), pack-reused 534Receiving objects: 100% (534/534), 748.44 KiB | 1.63 MiB/s, done.Resolving deltas: 100% (317/317), done.
    [my@my-wrk-lnv ~]$ git clone https://github.com/max-moser/network-manager-wireguardКлонирование в «network-manager-wireguard»…remote: Enumerating objects: 534, done.remote: Total 534 (delta 0), reused 0 (delta 0), pack-reused 534Получение объектов: 100% (534/534), 748.39 KiB | 3.55 MiB/s, готово.Определение изменений: 100% (317/317), готово.
  2. Go to the directory network-manager-wireguard and compile the plugin for the graphical configuration of the Wireguard tunnel:

    [my@my-wrk-lnv ~]$ cd network-manager-wireguard[my@my-wrk-lnv network-manager-wireguard](master)$ ./autogen.sh --without-libnm-gliblibtoolize: putting auxiliary files in '.'.libtoolize: linking file './ltmain.sh'libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.libtoolize: linking file 'm4/libtool.m4'libtoolize: linking file 'm4/ltoptions.m4'libtoolize: linking file 'm4/ltsugar.m4'libtoolize: linking file 'm4/ltversion.m4'libtoolize: linking file 'm4/lt~obsolete.m4'configure.ac:19: installing './compile'configure.ac:19: installing './config.guess'configure.ac:19: installing './config.sub'configure.ac:7: installing './install-sh'configure.ac:7: installing './missing'Makefile.am: installing './depcomp'parallel-tests: installing './test-driver'checking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking for a thread-safe mkdir -p... /bin/mkdir -pchecking for gawk... gawkchecking whether make sets $(MAKE)... yeschecking whether make supports nested variables... yeschecking whether UID '1000' is supported by ustar format... yeschecking whether GID '1000' is supported by ustar format... yeschecking how to create a ustar tar archive... gnutarchecking whether to enable maintainer-specific portions of Makefiles... yeschecking whether make supports nested variables... (cached) yeschecking for gcc-ar... gcc-archecking for gcc-ranlib... gcc-ranlibchecking build system type... x86_64-pc-linux-gnuchecking host system type... x86_64-pc-linux-gnuchecking how to print strings... printfchecking for style of include used by make... GNUchecking for gcc... gccchecking whether the C compiler works... yeschecking for C compiler default output file name... a.outchecking for suffix of executables... checking whether we are cross compiling... nochecking for suffix of object files... ochecking whether we are using the GNU C compiler... yeschecking whether gcc accepts -g... yeschecking for gcc option to accept ISO C89... none neededchecking whether gcc understands -c and -o together... yeschecking dependency style of gcc... gcc3checking for a sed that does not truncate output... /bin/sedchecking for grep that handles long lines and -e... /bin/grepchecking for egrep... /bin/grep -Echecking for fgrep... /bin/grep -Fchecking for ld used by gcc... /usr/bin/ldchecking if the linker (/usr/bin/ld) is GNU ld... yeschecking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -Bchecking the name lister (/usr/bin/nm -B) interface... BSD nmchecking whether ln -s works... yeschecking the maximum length of command line arguments... 1572864checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noopchecking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noopchecking for /usr/bin/ld option to reload object files... -rchecking for objdump... objdumpchecking how to recognize dependent libraries... pass_allchecking for dlltool... nochecking how to associate runtime and link libraries... printf %s\nchecking for archiver @FILE support... @checking for strip... stripchecking for ranlib... (cached) gcc-ranlibchecking command to parse /usr/bin/nm -B output from gcc object... okchecking for sysroot... nochecking for a working dd... /bin/ddchecking how to truncate binary pipes... /bin/dd bs=4096 count=1checking for mt... mtchecking if mt is a manifest tool... nochecking how to run the C preprocessor... gcc -Echecking for ANSI C header files... yeschecking for sys/types.h... yeschecking for sys/stat.h... yeschecking for stdlib.h... yeschecking for string.h... yeschecking for memory.h... yeschecking for strings.h... yeschecking for inttypes.h... yeschecking for stdint.h... yeschecking for unistd.h... yeschecking for dlfcn.h... yeschecking for objdir... .libschecking if gcc supports -fno-rtti -fno-exceptions... nochecking for gcc option to produce PIC... -fPIC -DPICchecking if gcc PIC flag -fPIC -DPIC works... yeschecking if gcc static flag -static works... yeschecking if gcc supports -c -o file.o... yeschecking if gcc supports -c -o file.o... (cached) yeschecking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yeschecking whether -lc should be explicitly linked in... nochecking dynamic linker characteristics... GNU/Linux ld.sochecking how to hardcode library paths into programs... immediatechecking whether stripping libraries is possible... yeschecking if libtool supports shared libraries... yeschecking whether to build shared libraries... yeschecking whether to build static libraries... nochecking for gcc... (cached) gccchecking whether we are using the GNU C compiler... (cached) yeschecking whether gcc accepts -g... (cached) yeschecking for gcc option to accept ISO C89... (cached) none neededchecking whether gcc understands -c and -o together... (cached) yeschecking dependency style of gcc... (cached) gcc3checking for glib-compile-resources... /usr/bin/glib-compile-resourceschecking for ANSI C header files... (cached) yeschecking fcntl.h usability... yeschecking fcntl.h presence... yeschecking for fcntl.h... yeschecking paths.h usability... yeschecking paths.h presence... yeschecking for paths.h... yeschecking sys/ioctl.h usability... yeschecking sys/ioctl.h presence... yeschecking for sys/ioctl.h... yeschecking sys/time.h usability... yeschecking sys/time.h presence... yeschecking for sys/time.h... yeschecking syslog.h usability... yeschecking syslog.h presence... yeschecking for syslog.h... yeschecking for unistd.h... (cached) yeschecking for mode_t... yeschecking for pid_t... yeschecking whether time.h and sys/time.h may both be included... yeschecking whether gcc needs -traditional... nochecking for working memcmp... yeschecking for select... yeschecking for socket... yeschecking for uname... yeschecking for library containing dlopen... -ldlchecking whether NLS is requested... yeschecking for intltool >= 0.35... 0.51.0 foundchecking for intltool-update... /usr/bin/intltool-updatechecking for intltool-merge... /usr/bin/intltool-mergechecking for intltool-extract... /usr/bin/intltool-extractchecking for xgettext... /usr/bin/xgettextchecking for msgmerge... /usr/bin/msgmergechecking for msgfmt... /usr/bin/msgfmtchecking for gmsgfmt... /usr/bin/msgfmtchecking for perl... /usr/bin/perlchecking for perl >= 5.8.1... 5.26.1checking for XML::Parser... okchecking locale.h usability... yeschecking locale.h presence... yeschecking for locale.h... yeschecking for LC_MESSAGES... yeschecking for CFPreferencesCopyAppValue... nochecking for CFLocaleCopyCurrent... nochecking libintl.h usability... yeschecking libintl.h presence... yeschecking for libintl.h... yeschecking for ngettext in libc... yeschecking for dgettext in libc... yeschecking for bind_textdomain_codeset... yeschecking for msgfmt... (cached) /usr/bin/msgfmtchecking for dcgettext... yeschecking if msgfmt accepts -c... yeschecking for gmsgfmt... (cached) /usr/bin/msgfmtchecking for xgettext... (cached) /usr/bin/xgettextchecking for pkg-config... /usr/bin/pkg-configchecking pkg-config is at least version 0.9.0... yeschecking for GLIB... yeschecking for GTK... yeschecking for LIBNMA... yeschecking for LIBSECRET... yeschecking for LIBNM... yeschecking for more warnings... yeschecking whether -Wunknown-warning-option works as expected... not supportedchecking whether "-Wextra" works as expected... yeschecking whether "-Wdeclaration-after-statement" works as expected... yeschecking whether "-Wfloat-equal" works as expected... yeschecking whether "-Wformat-nonliteral" works as expected... yeschecking whether "-Wformat-security" works as expected... yeschecking whether "-Wimplicit-fallthrough" works as expected... yeschecking whether "-Wimplicit-function-declaration" works as expected... yeschecking whether "-Winit-self" works as expected... yeschecking whether "-Wlogical-op" works as expected... yeschecking whether "-Wmissing-declarations" works as expected... yeschecking whether "-Wmissing-include-dirs" works as expected... yeschecking whether "-Wmissing-prototypes" works as expected... yeschecking whether "-Wpointer-arith" works as expected... yeschecking whether "-Wshadow" works as expected... yeschecking whether "-Wshift-negative-value" works as expected... yeschecking whether "-Wstrict-prototypes" works as expected... yeschecking whether "-Wundef" works as expected... yeschecking whether "-Wno-duplicate-decl-specifier" works as expected... yeschecking whether "-Wno-format-truncation" works as expected... yeschecking whether "-Wno-format-y2k" works as expected... yeschecking whether "-Wno-missing-field-initializers" works as expected... yeschecking whether "-Wno-pragmas" works as expected... yeschecking whether "-Wno-sign-compare" works as expected... yeschecking whether "-Wno-unused-but-set-variable" works as expected... yeschecking whether "-Wno-unused-parameter" works as expected... yeschecking whether -Wunknown-attributes works as expected... not supportedchecking whether -Wtypedef-redefinition works as expected... not supportedchecking whether -Warray-bounds works as expected... yeschecking whether -Wparentheses-equality works as expected... not supportedchecking whether -Wunused-value works as expected... yeschecking whether -Wmissing-braces works as expected... nochecking if gcc supports flag -fdata-sections -ffunction-sections -Wl,--gc-sections in envvar CFLAGS... yeschecking that generated files are newer than configure... doneconfigure: creating ./config.statusconfig.status: creating Makefileconfig.status: creating po/Makefile.inconfig.status: creating config.hconfig.status: executing depfiles commandsconfig.status: executing libtool commandsconfig.status: executing default-1 commandsconfig.status: executing po/stamp-it commandsBuild configuration: --with-gnome=yes--with-libnm-glib=no--enable-absolute-paths=no--enable-more-warnings=yes--enable-lto=no--enable-ld-gc=yes
    [my@my-wrk-lnv network-manager-wireguard](master)$ ./configure --without-libnm-glib --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib/x86_64-linux-gnu --libexecdir=/usr/lib/NetworkManager --localstatedir=/varchecking for a BSD-compatible install... /usr/bin/install -cchecking whether build environment is sane... yeschecking for a thread-safe mkdir -p... /bin/mkdir -pchecking for gawk... gawkchecking whether make sets $(MAKE)... yeschecking whether make supports nested variables... yeschecking whether UID '1000' is supported by ustar format... yeschecking whether GID '1000' is supported by ustar format... yeschecking how to create a ustar tar archive... gnutarchecking whether to enable maintainer-specific portions of Makefiles... nochecking whether make supports nested variables... (cached) yeschecking for gcc-ar... gcc-archecking for gcc-ranlib... gcc-ranlibchecking build system type... x86_64-pc-linux-gnuchecking host system type... x86_64-pc-linux-gnuchecking how to print strings... printfchecking for style of include used by make... GNUchecking for gcc... gccchecking whether the C compiler works... yeschecking for C compiler default output file name... a.outchecking for suffix of executables... checking whether we are cross compiling... nochecking for suffix of object files... ochecking whether we are using the GNU C compiler... yeschecking whether gcc accepts -g... yeschecking for gcc option to accept ISO C89... none neededchecking whether gcc understands -c and -o together... yeschecking dependency style of gcc... gcc3checking for a sed that does not truncate output... /bin/sedchecking for grep that handles long lines and -e... /bin/grepchecking for egrep... /bin/grep -Echecking for fgrep... /bin/grep -Fchecking for ld used by gcc... /usr/bin/ldchecking if the linker (/usr/bin/ld) is GNU ld... yeschecking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -Bchecking the name lister (/usr/bin/nm -B) interface... BSD nmchecking whether ln -s works... yeschecking the maximum length of command line arguments... 1572864checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noopchecking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noopchecking for /usr/bin/ld option to reload object files... -rchecking for objdump... objdumpchecking how to recognize dependent libraries... pass_allchecking for dlltool... nochecking how to associate runtime and link libraries... printf %s\nchecking for archiver @FILE support... @checking for strip... stripchecking for ranlib... (cached) gcc-ranlibchecking command to parse /usr/bin/nm -B output from gcc object... okchecking for sysroot... nochecking for a working dd... /bin/ddchecking how to truncate binary pipes... /bin/dd bs=4096 count=1checking for mt... mtchecking if mt is a manifest tool... nochecking how to run the C preprocessor... gcc -Echecking for ANSI C header files... yeschecking for sys/types.h... yeschecking for sys/stat.h... yeschecking for stdlib.h... yeschecking for string.h... yeschecking for memory.h... yeschecking for strings.h... yeschecking for inttypes.h... yeschecking for stdint.h... yeschecking for unistd.h... yeschecking for dlfcn.h... yeschecking for objdir... .libschecking if gcc supports -fno-rtti -fno-exceptions... nochecking for gcc option to produce PIC... -fPIC -DPICchecking if gcc PIC flag -fPIC -DPIC works... yeschecking if gcc static flag -static works... yeschecking if gcc supports -c -o file.o... yeschecking if gcc supports -c -o file.o... (cached) yeschecking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yeschecking whether -lc should be explicitly linked in... nochecking dynamic linker characteristics... GNU/Linux ld.sochecking how to hardcode library paths into programs... immediatechecking whether stripping libraries is possible... yeschecking if libtool supports shared libraries... yeschecking whether to build shared libraries... yeschecking whether to build static libraries... nochecking for gcc... (cached) gccchecking whether we are using the GNU C compiler... (cached) yeschecking whether gcc accepts -g... (cached) yeschecking for gcc option to accept ISO C89... (cached) none neededchecking whether gcc understands -c and -o together... (cached) yeschecking dependency style of gcc... (cached) gcc3checking for glib-compile-resources... /usr/bin/glib-compile-resourceschecking for ANSI C header files... (cached) yeschecking fcntl.h usability... yeschecking fcntl.h presence... yeschecking for fcntl.h... yeschecking paths.h usability... yeschecking paths.h presence... yeschecking for paths.h... yeschecking sys/ioctl.h usability... yeschecking sys/ioctl.h presence... yeschecking for sys/ioctl.h... yeschecking sys/time.h usability... yeschecking sys/time.h presence... yeschecking for sys/time.h... yeschecking syslog.h usability... yeschecking syslog.h presence... yeschecking for syslog.h... yeschecking for unistd.h... (cached) yeschecking for mode_t... yeschecking for pid_t... yeschecking whether time.h and sys/time.h may both be included... yeschecking whether gcc needs -traditional... nochecking for working memcmp... yeschecking for select... yeschecking for socket... yeschecking for uname... yeschecking for library containing dlopen... -ldlchecking whether NLS is requested... yeschecking for intltool >= 0.35... 0.51.0 foundchecking for intltool-update... /usr/bin/intltool-updatechecking for intltool-merge... /usr/bin/intltool-mergechecking for intltool-extract... /usr/bin/intltool-extractchecking for xgettext... /usr/bin/xgettextchecking for msgmerge... /usr/bin/msgmergechecking for msgfmt... /usr/bin/msgfmtchecking for gmsgfmt... /usr/bin/msgfmtchecking for perl... /usr/bin/perlchecking for perl >= 5.8.1... 5.26.1checking for XML::Parser... okchecking locale.h usability... yeschecking locale.h presence... yeschecking for locale.h... yeschecking for LC_MESSAGES... yeschecking for CFPreferencesCopyAppValue... nochecking for CFLocaleCopyCurrent... nochecking libintl.h usability... yeschecking libintl.h presence... yeschecking for libintl.h... yeschecking for ngettext in libc... yeschecking for dgettext in libc... yeschecking for bind_textdomain_codeset... yeschecking for msgfmt... (cached) /usr/bin/msgfmtchecking for dcgettext... yeschecking if msgfmt accepts -c... yeschecking for gmsgfmt... (cached) /usr/bin/msgfmtchecking for xgettext... (cached) /usr/bin/xgettextchecking for pkg-config... /usr/bin/pkg-configchecking pkg-config is at least version 0.9.0... yeschecking for GLIB... yeschecking for GTK... yeschecking for LIBNMA... yeschecking for LIBSECRET... yeschecking for LIBNM... yeschecking for more warnings... yeschecking whether -Wunknown-warning-option works as expected... not supportedchecking whether "-Wextra" works as expected... yeschecking whether "-Wdeclaration-after-statement" works as expected... yeschecking whether "-Wfloat-equal" works as expected... yeschecking whether "-Wformat-nonliteral" works as expected... yeschecking whether "-Wformat-security" works as expected... yeschecking whether "-Wimplicit-fallthrough" works as expected... yeschecking whether "-Wimplicit-function-declaration" works as expected... yeschecking whether "-Winit-self" works as expected... yeschecking whether "-Wlogical-op" works as expected... yeschecking whether "-Wmissing-declarations" works as expected... yeschecking whether "-Wmissing-include-dirs" works as expected... yeschecking whether "-Wmissing-prototypes" works as expected... yeschecking whether "-Wpointer-arith" works as expected... yeschecking whether "-Wshadow" works as expected... yeschecking whether "-Wshift-negative-value" works as expected... yeschecking whether "-Wstrict-prototypes" works as expected... yeschecking whether "-Wundef" works as expected... yeschecking whether "-Wno-duplicate-decl-specifier" works as expected... yeschecking whether "-Wno-format-truncation" works as expected... yeschecking whether "-Wno-format-y2k" works as expected... yeschecking whether "-Wno-missing-field-initializers" works as expected... yeschecking whether "-Wno-pragmas" works as expected... yeschecking whether "-Wno-sign-compare" works as expected... yeschecking whether "-Wno-unused-but-set-variable" works as expected... yeschecking whether "-Wno-unused-parameter" works as expected... yeschecking whether -Wunknown-attributes works as expected... not supportedchecking whether -Wtypedef-redefinition works as expected... not supportedchecking whether -Warray-bounds works as expected... yeschecking whether -Wparentheses-equality works as expected... not supportedchecking whether -Wunused-value works as expected... yeschecking whether -Wmissing-braces works as expected... nochecking if gcc supports flag -fdata-sections -ffunction-sections -Wl,--gc-sections in envvar CFLAGS... yeschecking that generated files are newer than configure... doneconfigure: creating ./config.statusconfig.status: creating Makefileconfig.status: creating po/Makefile.inconfig.status: creating config.hconfig.status: config.h is unchangedconfig.status: executing depfiles commandsconfig.status: executing libtool commandsconfig.status: executing default-1 commandsconfig.status: executing po/stamp-it commandsBuild configuration: --with-gnome=yes--with-libnm-glib=no--enable-absolute-paths=no--enable-more-warnings=yes--enable-lto=no--enable-ld-gc=yes
    [my@my-wrk-lnv network-manager-wireguard](master)$ makeXMLLINT not set and xmllint not found in path; skipping xml preprocessing.make all-recursivemake[1]: Entering directory «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing.Making all in .make[2]: Entering directory «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing.CC shared/nm-utils/src_libnm_utils_la-nm-shared-utils.loIn file included from ./shared/nm-default.h:49:0,from shared/nm-utils/nm-shared-utils.c:22:/usr/include/libnm/nm-version.h:155:30: warning: "NM_VERSION_1_10_14" is not defined, evaluates to 0 [-Wundef]#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_10_14^~~~~~~~~~~~~~~~~~CC shared/src_libnm_utils_la-utils.loIn file included from shared/nm-default.h:49:0,from shared/utils.c:22:/usr/include/libnm/nm-version.h:155:30: warning: "NM_VERSION_1_10_14" is not defined, evaluates to 0 [-Wundef]#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_10_14^~~~~~~~~~~~~~~~~~CCLD auth-dialog/nm-wireguard-auth-dialogITMRG appdata/network-manager-wireguard.metainfo.xmlGEN nm-wireguard-service.namemake[2]: Leaving directory «/home/my/network-manager-wireguard»Making all in pomake[2]: Entering directory «/home/my/network-manager-wireguard/po»MSGFMT de.gmoMSGFMT en_GB.gmomake[2]: Leaving directory «/home/my/network-manager-wireguard/po»make[1]: Leaving directory «/home/my/network-manager-wireguard»
    [my@my-wrk-lnv network-manager-wireguard](master)$ makeXMLLINT not set and xmllint not found in path; skipping xml preprocessing.make all-recursivemake[1]: вход в каталог «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing.Making all in .make[2]: вход в каталог «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing.CC shared/nm-utils/src_libnm_utils_la-nm-shared-utils.loIn file included from ./shared/nm-default.h:49:0,from shared/nm-utils/nm-shared-utils.c:22:/usr/include/libnm/nm-version.h:155:30: warning: "NM_VERSION_1_10_14" is not defined, evaluates to 0 [-Wundef]#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_10_14^~~~~~~~~~~~~~~~~~CC shared/src_libnm_utils_la-utils.loIn file included from shared/nm-default.h:49:0,from shared/utils.c:22:/usr/include/libnm/nm-version.h:155:30: warning: "NM_VERSION_1_10_14" is not defined, evaluates to 0 [-Wundef]#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_10_14^~~~~~~~~~~~~~~~~~ CCLD auth-dialog/nm-wireguard-auth-dialogITMRG appdata/network-manager-wireguard.metainfo.xmlGEN nm-wireguard-service.namemake[2]: выход из каталога «/home/my/network-manager-wireguard»Making all in pomake[2]: вход в каталог «/home/my/network-manager-wireguard/po»MSGFMT de.gmoMSGFMT en_GB.gmomake[2]: выход из каталога «/home/my/network-manager-wireguard/po»make[1]: выход из каталога «/home/my/network-manager-wireguard»
    [my@my-wrk-lnv network-manager-wireguard](master)$ sudo make install[sudo] password for my: XMLLINT not set and xmllint not found in path; skipping xml preprocessing.Making install in .make[1]: Entering directory «/home/my/network-manager-wireguard»>XMLLINT not set and xmllint not found in path; skipping xml preprocessing.make[2]: Entering directory «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing./bin/mkdir -p '/usr/lib/NetworkManager'/bin/bash ./libtool --mode=install /usr/bin/install -c src/nm-wireguard-service auth-dialog/nm-wireguard-auth-dialog '/usr/lib/NetworkManager'libtool: install: /usr/bin/install -c src/nm-wireguard-service /usr/lib/NetworkManager/nm-wireguard-servicelibtool: install: /usr/bin/install -c auth-dialog/nm-wireguard-auth-dialog /usr/lib/NetworkManager/nm-wireguard-auth-dialog/bin/mkdir -p '/usr/share/appdata'/usr/bin/install -c -m 644 appdata/network-manager-wireguard.metainfo.xml '/usr/share/appdata'/bin/mkdir -p '/etc/dbus-1/system.d'/usr/bin/install -c -m 644 nm-wireguard-service.conf '/etc/dbus-1/system.d'/bin/mkdir -p '/usr/lib/NetworkManager/VPN'/usr/bin/install -c -m 644 nm-wireguard-service.name '/usr/lib/NetworkManager/VPN'/bin/mkdir -p '/usr/lib/x86_64-linux-gnu/NetworkManager'/bin/bash ./libtool --mode=install /usr/bin/install -c properties/libnm-vpn-plugin-wireguard.la properties/libnm-vpn-plugin-wireguard-editor.la '/usr/lib/x86_64-linux-gnu/NetworkManager'libtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard.so /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard.solibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard.lai /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard.lalibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard-editor.so /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard-editor.solibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard-editor.lai /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard-editor.lalibtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /usr/lib/x86_64-linux-gnu/NetworkManagerdoneinstalling de.gmo as /usr/share/locale/de/LC_MESSAGES/NetworkManager-wireguard.moinstalling en_GB.gmo as /usr/share/locale/en_GB/LC_MESSAGES/NetworkManager-wireguard.momake[1]: Leaving directory «/home/my/network-manager-wireguard/po»
    [my@my-wrk-lnv network-manager-wireguard](master)$ sudo make install[sudo] пароль для my: XMLLINT not set and xmllint not found in path; skipping xml preprocessing.Making install in .make[1]: вход в каталог «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing.make[2]: вход в каталог «/home/my/network-manager-wireguard»XMLLINT not set and xmllint not found in path; skipping xml preprocessing./bin/mkdir -p '/usr/lib/NetworkManager'/bin/bash ./libtool --mode=install /usr/bin/install -c src/nm-wireguard-service auth-dialog/nm-wireguard-auth-dialog '/usr/lib/NetworkManager'libtool: install: /usr/bin/install -c src/nm-wireguard-service /usr/lib/NetworkManager/nm-wireguard-servicelibtool: install: /usr/bin/install -c auth-dialog/nm-wireguard-auth-dialog /usr/lib/NetworkManager/nm-wireguard-auth-dialog/bin/mkdir -p '/usr/share/appdata'/usr/bin/install -c -m 644 appdata/network-manager-wireguard.metainfo.xml '/usr/share/appdata'/bin/mkdir -p '/etc/dbus-1/system.d'/usr/bin/install -c -m 644 nm-wireguard-service.conf '/etc/dbus-1/system.d'/bin/mkdir -p '/usr/lib/NetworkManager/VPN'/usr/bin/install -c -m 644 nm-wireguard-service.name '/usr/lib/NetworkManager/VPN'/bin/mkdir -p '/usr/lib/x86_64-linux-gnu/NetworkManager'/bin/bash ./libtool --mode=install /usr/bin/install -c properties/libnm-vpn-plugin-wireguard.la properties/libnm-vpn-plugin-wireguard-editor.la '/usr/lib/x86_64-linux-gnu/NetworkManager'libtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard.so /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard.solibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard.lai /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard.lalibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard-editor.so /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard-editor.solibtool: install: /usr/bin/install -c properties/.libs/libnm-vpn-plugin-wireguard-editor.lai /usr/lib/x86_64-linux-gnu/NetworkManager/libnm-vpn-plugin-wireguard-editor.lalibtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/sbin" ldconfig -n /usr/lib/x86_64-linux-gnu/NetworkManagerdoneinstalling de.gmo as /usr/share/locale/de/LC_MESSAGES/NetworkManager-wireguard.moinstalling en_GB.gmo as /usr/share/locale/en_GB/LC_MESSAGES/NetworkManager-wireguard.momake[1]: выход из каталога «/home/my/network-manager-wireguard/po»
  3. Reboot the computer and check the availability of Wireguard settings in the Network Connections panel:

    Connecting to WireGuard VPN from Linux (3)

Configuring the connection to the Wireguard server:
  1. Generate Private and Public keys, as described in 'Installation and configuration options in the terminal' (2nd step).

    If the keys were previously generated in the system, you would need to view them in the terminal and copy them to the clipboard one by one:

    [my@my-wrk-lnv wireguard]$ sudo cat private-key0CwJzxW0yOG4I9XWl9Wo9nzpxen2G0VlTAxD7XEBVmE=[my@my-wrk-lnv wireguard]$ sudo cat public-keyM2LeCzN8mFLpa6Xz3BNHFgtNt8kY4wluiwt+NJFTgxk=
  2. Copy the Private key and paste it into the Private Key field of the tunnel settings:

    Connecting to WireGuard VPN from Linux (4)

  3. Copy the public key and paste it into the previously configuredWireGuard serverin the Public Key field.

    In the 'Allowed IPs' field, specify the address from which traffic will be allowed to the server in IP/bitmask format — 172.16.82.8/32

    Connecting to WireGuard VPN from Linux (5)

  4. In the 'Public Key' field, enter the public key of the server, which can be copied to your computer's clipboard from the WireGuard settings in the router's web interface:

    Connecting to WireGuard VPN from Linux (6)

    Connecting to WireGuard VPN from Linux (7)

    In the 'Allowed IPs' field, specify allowed IP addresses in IP/bitmask format — 172.16.82.1/32 (the internal server address) and 192.168.22.0/24 (address of the local segment of the Keenetic router).

    In the 'Endpoint' field, specify the public IP address or domain name of the WireGuard server and the listening port on which the WireGuard client will establish the connection.

    In the 'PersistentKeepalive' field, specify the frequency of attempts to check the availability of the remote side of the connection. Usually, a 3-5 second interval between checks is enough.

  5. In the IPv4 tab in the Routes section, add a route to the local network segment of the Keenetic router:

    Connecting to WireGuard VPN from Linux (8)

  6. Connect to the Wireguard server and ensure there are no error messages.

    To check the server availability, you can send ICMP packets to the IP address of the local segment of your Keenetic router:

    [my@my-wrk-lnv ~]$ ping -c 10 -s 100 192.168.22.1PING 192.168.22.1 (192.168.22.1) 100(128) bytes of data.108 bytes from 192.168.22.1: icmp_seq=1 ttl=64 time=5.40 ms108 bytes from 192.168.22.1: icmp_seq=2 ttl=64 time=6.60 ms108 bytes from 192.168.22.1: icmp_seq=3 ttl=64 time=7.99 ms108 bytes from 192.168.22.1: icmp_seq=4 ttl=64 time=7.04 ms108 bytes from 192.168.22.1: icmp_seq=5 ttl=64 time=6.31 ms108 bytes from 192.168.22.1: icmp_seq=6 ttl=64 time=7.42 ms108 bytes from 192.168.22.1: icmp_seq=7 ttl=64 time=6.55 ms108 bytes from 192.168.22.1: icmp_seq=8 ttl=64 time=7.14 ms108 bytes from 192.168.22.1: icmp_seq=9 ttl=64 time=8.47 ms108 bytes from 192.168.22.1: icmp_seq=10 ttl=64 time=7.52 ms--- 192.168.22.1 ping statistics ---10 packets transmitted, 10 received, 0% packet loss, time 9015msrtt min/avg/max/mdev = 5.402/7.049/8.470/0.834 ms

In this section:

Connecting to WireGuard VPN from Linux (2024)
Top Articles
Latest Posts
Article information

Author: Wyatt Volkman LLD

Last Updated:

Views: 5953

Rating: 4.6 / 5 (66 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Wyatt Volkman LLD

Birthday: 1992-02-16

Address: Suite 851 78549 Lubowitz Well, Wardside, TX 98080-8615

Phone: +67618977178100

Job: Manufacturing Director

Hobby: Running, Mountaineering, Inline skating, Writing, Baton twirling, Computer programming, Stone skipping

Introduction: My name is Wyatt Volkman LLD, I am a handsome, rich, comfortable, lively, zealous, graceful, gifted person who loves writing and wants to share my knowledge and understanding with you.