None

Configuring a Dedicated LAN Between Mac and Linux Machines

A quick reference for setting up a private Ethernet network between machines using static IPs.

Background

Every now and again I find myself needing to network a couple machines. But not often enough where I can remember every step off the top of my head. These are my notes for networking my Mac to a Linux box I run headless, including basic SSH and firewall configurations.

IP Address (Remote)

I'll start with my Linux machine running Ubuntu 24.04. Because there isn't an SSH server installed by default (openssh-server), I'll plug in a keyboard, mouse and monitor until we make that service available.

The first step is to create a Netplan config file containing information about our network setup, interfaces and IP addresses. This file will live in /etc/netplan/. Whereas with .nmconnection files we generally prefix the file with the interface (e.g. enp0s0.nmconnection), here we can use the role of the file (##-networkname.yaml). Furthermore, we prefix with an integer indicating the priority of the network policy with "01" commonly being used for default policies. The higher the number, the greater the priority.

# /etc/netplan/10-direct-ethernet.yaml

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    <interface>:  # e.g., enp0s0, enp3s0 — find with 'ip link show'
      dhcp4: no
      dhcp6: no
      accept-ra: no
      link-local: []
      addresses:
        - 192.168.50.10/24

This article is meant for quick reference but I'll hit these values quickly:

  • We use version: 2 because it's currently the only supported value.
  • The renderer is specified as NetworkManager because I'm on Ubuntu Desktop and that's the default option. If this was a server, I'd likely use systemd-networkd instead.
  • We specify the interface under ethernets because I'm establishing an ethernet connection. If this was a WiFi connection you would use wifis and you'd need to provide credentials (access-points). Find your interfaces and their respective status with ip link show. Replace <interface> with the actual interface name.
  • The dhcp4, dhcp6, accept-ra, and link-local properties are structured for a network without a DHCP server.
  • Last, we specify the IP address and subnet information for this machine in CIDR format telling us we have an IPv4 address of 192.168.50.10 with a Network Address of 192.168.50.0 a Broadcast Address of 192.168.50.255, and a Subnet Mask of 255.255.255.0.

With the Netplan config file established, we're ready to activate the network. First I like to run try or generate first as a sanity check before running apply.

# check for syntax errors
sudo netplan generate  # will raise exceptions
# same thing, but has a built-in rollback/timeout mechanism
# sudo netplan try  

# if all is well, bring the configuration live
sudo netplan apply

After running these commands, we'll find that a .nmconnection file was created in /run/NetworkManager/system-connections/.

ian@skynet:~$ ls -l /run/NetworkManager/system-connections/
total 12
-rw------- 1 root root 314 Feb 11 11:04 lo.nmconnection  # loopback connection
-rw------- 1 root root 168 Feb 11 11:04 netplan-enp0s0.nmconnection  # what we applied
# my wifi connection etc...

If we want to take down this network connection, we delete the Netplan config and run apply once more, not the .nmconnection file.

rm /etc/netplan/10-direct-ethernet.yaml

sudo netplan apply

ian@skynet:~$ ls -l /run/NetworkManager/system-connections/
total 12
-rw------- 1 root root 314 Feb 11 11:04 lo.nmconnection

IP Address (Local)

Next, we'll configure the IPv4 address of the Mac on the subnet. This is easily accomplished through the interface located at "Settings > Network," select the interface (probably "Ethernet" if you're plugged into the ethernet adapter), and click "Details." On the "TCP/IP" tab set "Configure IPv4" to "Manually" and enter values for the "IP address" and "Subnet mask" fields. I'll increment the IP address by 10 from what we used for the remote: 192.168.50.20.

 

IP Assignment Conventions

If one machine on a subnet has a server-type role (headless, etc.), I assign the lowest host value to this machine (10 in our case). Then clients are incremented from there as they're added to the network (20, 30, etc.). If no machine has a particular role that stands out, assign at your discretion.

Screen shot of Mac network configuration window.

Select "OK" and we're done.

Test Connections

With our networks configured in both directions, these machines should be visible to one another. Starting from the Mac I'll ping the remote.

ianwaldron@Ians-Mac-mini ~ % ping -c 3 192.168.50.10
PING 192.168.50.10 (192.168.50.10): 56 data bytes
64 bytes from 192.168.50.10: icmp_seq=0 ttl=64 time=0.627 ms
64 bytes from 192.168.50.10: icmp_seq=1 ttl=64 time=0.581 ms
64 bytes from 192.168.50.10: icmp_seq=2 ttl=64 time=0.658 ms

--- 192.168.50.10 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.581/0.622/0.658/0.032 ms

And then let's test the remote can see the Mac.

ian@skynet:~$ ping -c 3 192.168.50.20
PING 192.168.50.20 (192.168.50.20) 56(84) bytes of data.
64 bytes from 192.168.50.20: icmp_seq=1 ttl=64 time=0.237 ms
64 bytes from 192.168.50.20: icmp_seq=2 ttl=64 time=0.227 ms
64 bytes from 192.168.50.20: icmp_seq=3 ttl=64 time=0.415 ms

--- 192.168.50.20 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2061ms
rtt min/avg/max/mdev = 0.227/0.293/0.415/0.086 ms

Good connections, great!

As a side note, we're also able to ping these machines using the hostnames they broadcast using the .local reserved domain because Mac has Bonjour installed by default and Ubuntu has Avahi enabling mDNS hostname resolution.

ianwaldron@Ians-Mac-mini ~ % ping -c 1 skynet.local
PING skynet.local (192.168.50.10): 56 data bytes
64 bytes from 192.168.50.10: icmp_seq=0 ttl=64 time=0.524 ms

--- skynet.local ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.524/0.524/0.524/0.000 ms

SSH

With a good network connection, we're ready to set up SSH. The Mac is ready to go out of the gate for outbound SSH connections. For the headless rig to receive connections, however, we need to configure openssh-server.

sudo apt install openssh-server

# then we can confirm it's running with:
systemctl status ssh

Back on the Mac we're ready to copy an SSH public key over to the remote.

ssh-copy-id ian@192.168.50.10

# if you don't already have a key generated:
# ssh-keygen -t ed25519

Follow the prompts to add the public key to the authorized_keys file on the remote and we'll be good to go.

At this point we no longer need the keyboard, mouse, and monitor connected to the Linux machine. We can finish the configuration entirely over SSH.

Lock-Down SSH

It's also good practice to lock down SSH to public key authorization only (disable password authentication) and disable root login. We'll SSH into the remote and update that configuration.

sudo nano /etc/ssh/sshd_config

Look for the following and configure accordingly (they won't be consecutive):

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no

And now SSH should be in a good spot.

Firewall

Last but not least, we'll lock down the remote machine by enabling the UFW firewall shipped with Ubuntu out of the box. The firewall isn't enabled by default. We know this because we have an active SSH connection to the machine. If the firewall were active, the incoming connection would have been dropped. 

Default rules for UFW look like:

Default: deny (incoming), allow (outgoing), disabled (routed)

All incoming connections are dropped by default. Therefore, we want to add a rule for incoming connections to port 22 for our particular machine

ian@skynet:~$ sudo ufw allow from 192.168.50.20 to any port 22
Rule added

# alternatively add the subnet as a whole if we want other 
#   machines on the same subnet to have access
sudo ufw allow from 192.168.50.0/24 to any port 22

Now we enable the firewall.

ian@skynet:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
 

Risk of lockout!

If you enable the firewall prior to allowing SSH on port 22 you will lock yourself out!

And there you have it. We're now set up to only allow incoming connections from the Mac on our particular subnet and only on port 22 (SSH).

Final Thoughts

Networking a Mac and a Linux machine is a relatively simple task. However, there are a number of steps to check off and considerations to make. This has been a short discussion on how to make a point-to-point connection between a Mac and a Linux machine, including establishing SSH and a basic firewall.

You don't need to memorize the process but it's good to have a general familiarity. As AI consumes more and more of the application layer, understanding how the pieces fit together and making machines talk reliably and securely will be an increasingly important role for the software engineer.

Details
Published
February 13, 2026
Next
August 1, 2025

Managing Multiple GitHub Accounts with SSH Keys

A step-by-step guide to configuring SSH for seamless pushes to different GitHub remote repositories across accounts on macOS.