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 port 9 or another dedicated port on your router’s public IP Address. That port will be forwarded to port 9 on the sleeping server’s local IP Address. Port 9 (the “discard service” port) is used simply as a way to get the packet routed to the internal server without undesirable side-effects.
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 designated port on it’s public IP to port 9 on 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. You may need to also enable this in the
BIOS.
For a Linux server, 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:
[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.
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 (7));
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
(6).
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:
Port 9, forwarded from a port on the public IP 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 silently dropped by the server. 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 4000 (forwarded from port 4001 on the
public IP Address).
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.