There is a simple guide at https://oracle-base.com/articles/linux/use-iptables-to-implement-packet-filtering-and-configure-nat. But I found out, that in Windows, the DNS address that the Linux PC is using, must also be given in Windows.
I have a 3G USB modem connected to my Linux PC, and from that I have two Windows PC's that get internet. It's called (kernel) packet forwarding, and it's quite simple and quick to do - when you understand it finally.
You will need to find out your network interfaces names by running the command "ifconfig" on Linux (in the terminal), and "ipconfig" on Windows (in the command prompt). The interface names, on Linux, are at the leftmost side, like: enp2s0, enp3s0, enp0s18f2u6, lo. Now you set up packed forwarding:
First you need to enable packet forwarding on your Linux PC (see that guide I linked from oracle-base.com).
Next, you can run these commands, as that oracle-base.com guide says (but wait, and read on):
sudo iptables -I FORWARD -i my_lan_interface -o my_modem_interface -j ACCEPT
sudo iptables -I FORWARD -i my_modem_interface -o my_lan_interface -j ACCEPT
sudo iptables -t nat -I POSTROUTING -o my_modem_interface -j MASQUERADE
But there is a more robust way, that I found on the net:
sudo iptables -t nat -A POSTROUTING -o my_modem_interface -j MASQUERADE --random
sudo iptables -A FORWARD -i my_lan_interface -o my_modem_interface -j ACCEPT
sudo iptables -A FORWARD -i my_modem_interface -o my_lan_interface -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -j DROP
Here's an explanation for the commands just above (the "more robust" example), in the same order:
- First command: enable masquerading on my_modem_interface so the source address is rewritten on outgoing packets. The --random flag is to have symmetric NAT.
Now we are going to configure forwarding rules. iptables, by default, will unconditionally forward all traffic. Here we prefer to restrict inbound traffic from the internet and allow all outgoing:
- Second command: Allow traffic from my_lan_interface to my_modem_interface.
- Third command: Allow returning traffic from my_modem_interface to my_lan_interface.
- Fourth command: Drop all other traffic that shouldn't be forwarded.
When you reboot your Linux PC, you will have to reenter these commands - I have a script that runs them at each boot. You can make these changes permanent with the appropriate "service" call (again, see the oracle-base.com guide given above), but I recommend running them at each boot (in a script), as you might want to experiment and change things, and undoing what you saved is another challenge. If something goes wrong, or you want to change things, or you just don't want this feature for your current session (or at all), then just reboot your PC and they're gone - but you must disable packet forwarding yourself (before rebooting write "net.ipv4.ip_forward = 0" in /etc/sysctl.conf) to fully disable this technology.
Now you have to create a network connection (Ethernet connection) between your Linux PC and your other computers. For example:
A) On the Linux PC connected to the internet (I use Fedora), with the network connections manager, I create an Ethernet connection, select the appropriate interface (network card name, enp3s0 in my case) that will connect this Linux PC to my LAN. Be sure to select the right firewall zone or your LAN will not get internet. So since this is your internal LAN interface, set the firewall zone to "trusted", but the modem connection interface should be set to "public". Next, in the IPv4 settings tab, set that IPv4 must be used for the connection (IPv6 can be ignored), and select manual address setup. Now add the address 192.168.2.100 - this will be the address of this Linux PC on your LAN. The net mask will be set automatically (255.255.255.0, because this is a "C class" (private) address). Apply your settings and connect.
B) On the second PC (with Linux or Windows, connected by Ethernet cable to the first one above), also create a network connection (if it's Windows, look below for better details), select the appropriate network interface (the device/card which is connecting to the first PC), use manual IPv4 setup as above for the first PC, but here set the address 192.168.2.101 - this will be the address of this second PC on your LAN (these are "private" addresses, meaning that they will not be visible outside your LAN).
B1) If you want to connect Windows (operating system), go to "Network and Sharing Center"->"change adapter settings", and look for your network interface that corresponds to your LAN network card on this Windows PC, which is also connected by Ethernet cable to the first PC. Now, select that interface, right click for Properties. You will see a list. Here unselect "Internet Protocol Version 6" and double click on "Internet Protocol Version 4". Now you enter the address 192.168.2.101 - this will be the address of this Windows PC on that interface (on that [LAN/Ethernet] connection)). Tab down so netmask is filled out automatically (255.255.255.0). (The "Network Profile" can be set to "public".)
B2) It might be necessary to set the gateway address to the first Linux PC, so you would need to enter as gateway address 192.168.2.100.
C) Now, you must enter the DNS address that your first Linux PC is using. For example, my modem uses DNS address 192.168.1.1 (which I can find with the command "nmcli device show | grep IP4.DNS", where interfacename is the name of your Linux interface connected to the internet). (If you connect to the internet with Windows, run "ipconfig" in the terminal/command prompt, look for a DNS address). And that's it. The DNS information is critical to getting an internet connection.
So putting it short:
My modem address: 192.168.1.100, DNS 192.168.1.1.
Linux PC address on LAN: 192.168.2.100, packet forwarding enabled with iptables redirecting traffic, as explained above, firewall zone set to "trusted".
Windows PC 1 address: 192.168.2.101 with DNS set to 192.168.1.1, network profile set to public. (Default gateway set to Linux PC: 192.168.2.100).
Windows PC 2 address: 192.168.2.102 with DNS set to 192.168.1.1, network profile set to public. (Default gateway set to Linux PC: 192.168.2.100).
(All computers connected together by a simple Ethernet switch with plain Ethernet cables (also called "patch cables" or "patch cords"), not crossed, because "modern" network cards do the crossing by themselves, so you can use crossed cables or not crossed cables, even mix them together in a connection.)
There is also a guide at: https://medium.com/@TarunChinmai/sharing-internet-connection-from-a-linux-machine-over-ethernet-a5cbbd775a4f, which uses Google's DNS addresses instead. Check it out.