NoMachine currently (as of 8.11.3) only supports waking up a
sleeping server on the local network.
It is possible to wake up a machine over the Internet using a separate utility and “advanced” routing and DDNS. Here’s how. If you already know the basics, skip to “Step by Step Instructions”.
A server is awakened when it’s network interface receives a “magic packet” containing that interface’s own MAC Address encoded in a certain way. The supposedly-powered-off machine must keep some logic powered so it can listen for the magic packet; this must be enabled in the OS and BIOS.
WoL may only work from certain sleep states and not from a “power off” state (or vice-versa). It depends on the host’s hardware and firmware.
The “magic packet” data pattern is 6 bytes of 0xFF followed by 16 repetitions of the 6-byte MAC Address. This can appear anywhere within the packet and it does not matter what kind of packet it is or what protocol was used to send it.
A link-level broadcast is usually used for local WoL because it reaches every device on the local net without special routing. This will not work over the Internet, which only handles IP packets. To route WoL over the Internet, you must manage routing to get the packet delivered to the powered-off server’s NIC.
IP (Internet Protocol) operates over Ethernet and other link-level protocols. IP is a foundation on which TCP and UDP operate. TCP provides a “reliable stream” but can not work if one end is sleeping or powered off. UDP is an “unreliable datagram” service which requires no cooperation from the receiving end – and therefore is perfect for our needs.
An IP Address identifies a specific network interface. Routers have multiple interfaces and multiple IP addresses. “Public” IP Addresses are globally unique and can be used on the Internet; they are assigned by domain administrators. “Private network” addresses such as 192.168.x.y may be used by anyone inside a private network, but are not unique and may never be used on the Internet.
Network Address Translation (NAT) is used by routers when local hosts use private-network IP addresses. The router acts as a transparent proxy when local hosts communicate with Internet hosts by exchanging its own public IP address with the local hosts’ private addresses in all packets in a conversation. Thus local hosts do nothing special – they talk to public IP addresses on the Internet the same way they talk to private-network addresses used by local hosts. However, the reverse is not true – an Internet host can not explicitly contact a local host; it can only contact the router using the router’s public IP address.
A Port Number identifies a software end-point within an IP Address, allowing many concurrent conversations to use the same IP Address. A UDP packet specifies both sender and receiver with [IP Address, Port Number] pairs. “Well known” port numbers are used by servers that listen for unsolicited requests; for example port 80 is for http (web server) and port 9 is for a “discard service” (accepts anything and discards it, ala /dev/null).
“Port Forwarding” is where a router relays packets received from the Internet at a specific Port Number to an internal IP Address. This allows an external host to initiate contact with a local host when NAT is being used. However a unique Port Number (at the router’s public IP Address) must be used for each point of contact. The port number the router receives the packet on can be different than the port number the packet is forwarded to.
Some kind of IP packet must be used so it can travel through IP routers and eventually to the physical LAN segment connected to the sleeping server.
We will use a UDP packet containing the WoL magic bytes, sent to an otherwise-unused port at your router’s public IP Address, which the router forwards to Port 9 at the sleeping server’s local IP Address (port 9, used by a “discard service” is used so that if the server is already awake it won’t do anything harmful). For simplicity, people often also use port 9 on the public IP Address, but this is not necessary.
In fact, multiple public port numbers can be used if you have multiple wakeup-able hosts (all the forwarded ports would be forwarded to port 9 on the corresponding local IP Addresses).
Some routers allow port-forwarding to an IP broadcast address on the LAN instead of to a single IP address. This might simplify the setup (i.e. for multiple hosts or to avoid ARP Binding – see blow) but could increase the attack surface by making every device on the LAN respond to a packet sent from the Internet. Therefore I don’t recommend doing this unless you have a large number of wakeup-able hosts or ARP Binding is not supported by your router.
A utility is needed on the client machine, such as your laptop, that can send the UDP packet to your DDNS (or static) public IP hostname. A simple Perl script which does this can be downloaded from https://abhweb.org/downloads/wol_wakeup_script.pl
The main requirements:
Your router or an always-on local host must support DDNS unless your ISP provided a static public IP Address.
The powered-off server must have an effectively-static local IP address.
Your router must forward UDP packets from the Internet to the server’s IP address.
Your router must route that IP to the powered-off server’s NIC without depending on the server to respond to ARP or similar requests.
Prefer a wired network for the server, not Wi-Fi. Some WiFi interfaces can listen for a WoL packet when their host is powered off, but not all of them can. If you must use WiFi, confirm what WoL works (on the local network) before proceeding.
Assign a fixed local IP address to the
server: It is usually easiest to use the DHCP Address
Reservation feature in your
router to reserve a particular IP address for the MAC Address
of the server which will be awakened by WoL. No change is made to
the server – it will still use DHCP to request an IP address but
will always get the same answer.
To assign a true
static IP: Configure your router to allocate only a subset of its
private
network range to DHCP clients (for example 192.168.1.2 through
.199), and pick an address outside of that subset but still within
the private network range as the server’s static IP (such as
192.168.1.200). Then configure the server to use the assigned IP
address and not use DHCP.
Use “MAC Binding” in your router to statically
associate your server’s IP with it’s MAC Address.
This obviates the need for the server to respond to ARP,
which it can not do while
sleeping. Be careful that
DHCP Address Reservation and MAC Binding use the same IP:MAC
pairing!
Reboot
both your router and server machine to verify that everything still
works.
Enable Wake-on-Lan in your server’s network interface. The method depends on the OS.
For Ubuntu 24.04 or
other Linux flavors which use the “NetworkManager”:
GUI
Method (Ethernet only, not WiFi): Run “Advanced Network
Configuration” from the system start menu or GNOME overview, or
run the command nm-connection-manager
in a terminal.
Under the “Ethernet” tab, select your
interface, check the Wake on LAN “Magic” checkbox, and click
“Save”.
Command line Method (Ethernet):
nmcli connection
show
Look for your network name (this example assumes
“netplan-enp0s31f6”).
nmcli
connection show "netplan-enp0s31f6" | grep 802
Look for “802...wake-on-lan:”. If it is set to “magic” it
is already enabled. Otherwise…
nmcli
connection modify "netplan-enp0s31f6"
802-3-ethernet.wake-on-lan magic
to enable it. Reboot.
If you must use a WiFi with WOL
see
https://ubuntuhandbook.org/index.php/2024/08/enable-wake-on-lan-ubuntu/
For Ubuntu 23.04 and
earlier (or other Linux
without “NetworkManager”):
Run ip
a and find the nic name (e.g. “enp0s31f6” might be an
Ethernet port).
Then sudo ethtool
<nic name> | grep Wake : If “Supports Wake-on”
contains the letter ‘g’ then WoL is supported (if it
isn’t then you may have to enable something in the BIOS).
If
“Wake-on” contains ‘g’ then WoL is currently
enabled; ‘d’ means disabled.
To permanently enable
WoL (valid in Ubuntu 23.04):
sudo
--preserve-env systemctl edit --force --full
wol-enable.service
which starts an editor. Edit the
file if necessary to contain the following, then write it back:
#
optional comment
[Unit]
Description=Enable
Wake-up on LAN
[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s <nic name> wol g
[Install]
WantedBy=basic.target
Finally, run sudo
systemctl daemon-reload and
sudo
systemctl enable wol-enable.service .
Shut down your server and remove power to erase any state in the NIC. Then power up and reboot, and rerun ethtool <nic name> | grep Wake to verify that WoL was re-enabled on the interface (“Wake-on” should contain ‘g’ and not ‘d’).
Verify that WoL works locally. Put your server to sleep and try to wake it up from another host on the LAN using NoMachine’s built-in local WoL support.
Set up
public-key-based NoMachine authentication and disable passwords.
You will need to put the public key into
$HOME/.nx/config/authorized.crt on the Linux server and the private
key in a file in your client machine, and configure the NoMachine
client connection to use it.
Instructions are at
https://kb.nomachine.com/AR02L00785
Note:
It is prudent to never expose password-protected services to the
Internet.
Forward
NoMachine’s NX service from the Internet to your server
using “Port Forwarding” in your router.
The NX
service uses port 4000 by default, which should not be changed. To
help with testing, I suggest forwarding a different port number
from the Internet, e.g. 4001, to port 4000 on your local server.
To test: In another host, which could be on the
same LAN, run NoMachine as a client and create a connection profile
which uses your machine’s public IP address and port 4001.
For the moment, find out your public IP from your router or by
visiting https://whatismyipaddress.com/
If
NoMachine works, you can be sure the connection actually used the
port-forwarding and didn’t somehow go directly to the server.
Install a WoL utility on your client machine.
A simple Perl script is at
https://abhweb.org/downloads/wol_wakeup_script.pl
Use
Notepad or another editor to change the configuration settings at
the top of the file:
Set $target_mac to your
server’s MAC address
Set $fqdn_or_ip to your public
IP address for now (“aaa.bbb.ccc.ddd”) unless
you
already have a DDNS public domain name.
If your client is a Windows machine, install Strawberry Perl from
https://strawberryperl.com/
(“System installer version”). Then double-click the file
containing the wakeup script. If prompted for which application to
use for .pl files, click “other” and navigate to the perl
executable which by default is at C:\Strawberry\perl\bin\perl.exe .
If instead the file opens with Notepad etc. you can right-click the
file, then Properties, and change “Opens With”.
After
this initial setup, double-clicking the script file will run it,
sending the WoL packet.
To test, run sudo
tcpdump -v -UlnXi <nic name> udp port 9 in a terminal
on your server. Each time a UDP packet is sent to port 9 it will
display the contents. Then run the wakup script on your client –
you should see a hexadecimal dump of the UDP packet from tcpdump on
the server.
If that works, put your server to sleep and
check that it wakes up when you send the WoL packet.
Get a DDNS domain name (unless your public IP is
static)
You arrive at that cafe in Paris. Meanwhile,
your ISP back home has changed the public IP address of your router.
You need to find out what your new public IP is so you can call
home.
The solution is a Dynamic
DNS (DDNS) domain name which
automatically tracks the
IP assigned by your ISP.
This
works by having your router (or an always-on local host) log
into the DDNS
service
provider whenever
your public IP address changes
or at regular intervals.
The DDNS service will detect
your public IP address and update the DNS maps accordingly.
I
recommend https://www.noip.com/
. You can get a free
domain name
such as yourname.hopto.org
.
A completely-custom domain name is also possible.
Test connecting via the Internet:
On your
client machine, create or edit a NoMachine client connection
profile:
In the “Address” section: Set “Host”
to your public (DDNS) IP hostname and port to 4001
(assuming
you followed the suggestion in step 8));
In the “Configuration” section check “Use key-based
authentication with key you provide”
and navigate to the
path of the file containing the private key created in step
7).
Click
“Connect” to verify that you can connect to the server over the
Internet when it is already powered on.
Test remote WoL
Shut down or sleep your server,
and power off your router for a minute to ensure that it forgets any
transient routing tables. Then turn the router on and wait a minute
or so for it to boot up.
Connect your client machine to
the Internet via some other means, such as your neighbor’s WiFi or
a cellphone hotspot.
Edit the wakup Perl script
(rightclick→Edit or open with Notepad). Change $fqdn_or_ip to
your public (DDNS) IP hostname; save the file.
Drum-roll!
Double-click the wakeup script. Your server should come to life.
Connect to the server using the NoMachine connection
profile created above.
Celebrate.
Port-forwarding exposes your LAN to Denial-Of-Service attacks where someone constantly floods forwarded ports with packets, which then must traverse your LAN before being (hopefully) discarded.
A more serious concern is security vulnerabilities in the software services behind forwarded ports.
In the application described here, two ports are forwarded:
The port you chose (forwarded to port 9 on the local server), used to route a WoL packet to a sleeping server. Preferably the server does not enable any service for port 9, so packets sent there will be dropped by the kernel. If the server does enable port 9 by default, the “discard service” should run, which simply reads the packet and discards the content. We hope the Discard Service has no security vulnerabilities such as buffer-overflow bugs.
Port 4001 (forwarded to port 4000 on the local
server).
This is the NoMachine NX service. The whole point of
this exercise is to remotely access this service, so there is no
choice but to make it available on the Internet. This is unsafe if
password-based access is enabled because attackers can and do crack
passwords. If public-key authentication is the only enabled
authorization method, then NoMachine should be secure from attackers
who do not have access to the private key.
The client
machine has the private key, and so is vulnerable to theft or
exfiltration. For maximum security, the client key file could be
located on a USB drive, permanently mapped to a drive letter so it’s
path can be referenced in the NoMachine connection profile. Then
the USB drive could be plugged in only briefly, during the initial
authentication phase.