Internet sharing: Difference between revisions
Aaron Chen (talk | contribs) m (Add zh-hans link) |
m (→With nftables: style fix, we can't nest templates anchors and have them keep style, that's why Help:Style/Formatting and punctuation#Links, grammar fix to avoid contraction) |
||
(48 intermediate revisions by 28 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Network sharing]] | [[Category:Network sharing]] | ||
[[fr:Internet sharing]] | |||
[[fr | |||
[[ja:インターネット共有]] | [[ja:インターネット共有]] | ||
[[ru:Internet sharing]] | [[ru:Internet sharing]] | ||
[[zh-hans:Internet sharing | [[zh-hans:Internet sharing]] | ||
{{Related articles start}} | {{Related articles start}} | ||
{{Related|Android tethering}} | {{Related|Android tethering}} | ||
Line 20: | Line 18: | ||
== Requirements == | == Requirements == | ||
The machine acting as server should have an additional network device. That network device requires a functional [[ | The machine acting as server should have an additional network device. That network device requires a functional [[Wikipedia:Data link layer|data link layer]] to the machine(s) that are going to receive internet access: | ||
* To be able to share internet to several machines a [[Wikipedia:Network switch|switch]] can provide the data link. | |||
* To be able to share internet to several machines a [[Wikipedia:Network switch|switch]] can provide the data link layer connection. | |||
* A wireless device can share access to several machines as well, see [[Software access point]] first for this case. | * A wireless device can share access to several machines as well, see [[Software access point]] first for this case. | ||
* If you are sharing to only one machine, a [[Wikipedia:Ethernet crossover cable|crossover cable]] is sufficient. In case one of the two computers' ethernet cards has [[ | * If you are sharing to only one machine, a [[Wikipedia:Ethernet crossover cable|crossover cable]] is sufficient. In case one of the two computers' ethernet cards has [[Wikipedia:Medium Dependent Interface#Auto_MDI-X|MDI-X]] capability, a crossover cable is not necessary and a regular ethernet cable can be used. Executing {{ic|ethtool ''interface'' <nowiki>|</nowiki> grep MDI}} as root helps to figure it. | ||
== Configuration == | == Configuration == | ||
This section assumes | This section assumes that the network device connected to the client computer(s) is named {{ic|net0}} and the network device connected to the internet as {{ic|internet0}}. | ||
{{Tip|You can rename your devices to this scheme using [[ | {{Tip|You can rename your devices to this scheme using [[udev#Setting static device names]].}} | ||
All configuration is done on the server computer, except for the final step of [[#Assigning IP addresses to the client PC(s)]]. | All configuration is done on the server computer, except for the final step of [[#Assigning IP addresses to the client PC(s)]]. | ||
Line 36: | Line 35: | ||
On the server computer, assign a static IPv4 address to the interface connected to the other machines. The first 3 bytes of this address cannot be exactly the same as those of another interface, unless both interfaces have netmasks strictly greater than /24. | On the server computer, assign a static IPv4 address to the interface connected to the other machines. The first 3 bytes of this address cannot be exactly the same as those of another interface, unless both interfaces have netmasks strictly greater than /24. | ||
# ip link set up dev net0 | # ip link set up dev net0 | ||
# ip addr add 192.168.123.100/24 dev net0 # arbitrary address | # ip addr add 192.168.123.100/24 dev net0 # arbitrary address | ||
To have your static | To have your static IP assigned at boot, you can use a [[network manager]]. | ||
=== Enable packet forwarding === | === Enable packet forwarding === | ||
{{Warning|Enabling IP forwarding without a properly configured [[firewall]] is a security risk.}} | |||
To check the current packet forwarding settings, run: | |||
# sysctl -a | grep forward | # sysctl -a | grep forward | ||
You will note | You will note options for controlling forwarding per default, per interface, as well as separate options for IPv4/IPv6 per interface. For detailed description of all available options, see [https://docs.kernel.org/networking/ip-sysctl.html the kernel documentation]. | ||
To enable IPv4 and IPv6 packet forwarding, [[Sysctl#Configuration|configure sysctl]] to set these settings: | |||
net.ipv4.ip_forward = 1 | |||
net.ipv4.conf.all.forwarding = 1 | |||
net.ipv6.conf.all.forwarding = 1 | |||
{{ | {{Tip|To enable packet forwarding selectively for a specific interface, use {{ic|1=net.''ipv[46]''.conf.''interface_name''.forwarding=1}} instead.}} | ||
{{Warning|If the system uses [[systemd-networkd]] to control the network interfaces, a per-interface setting for IPv4 is not possible, i.e. systemd logic propagates any configured forwarding into a global (for all interfaces) setting for IPv4. The advised work-around is to use a firewall to forbid forwarding again on selective interfaces. See the {{man|5|systemd.network}} manual page for more information. The {{ic|1=IPForward=kernel}} semantics introduced in a previous systemd release 220/221 to honor kernel settings does not apply anymore.[https://github.com/poettering/systemd/commit/765afd5c4dbc71940d6dd6007ecc3eaa5a0b2aa1] [https://github.com/systemd/systemd/blob/a2088fd025deb90839c909829e27eece40f7fce4/NEWS]}} | |||
{{ | |||
To make changes persistent across reboots, see [[Sysctl#Configuration]]. You might consider writing settings to a file with a descriptive filename, such as {{ic|/etc/sysctl.d/30-ipforward.conf}}. | |||
Afterwards it is advisable to double-check forwarding is enabled as required after a reboot. | Afterwards it is advisable to double-check forwarding is enabled as required after a reboot. | ||
=== Enable NAT === | === Enable NAT === | ||
==== With iptables ==== | |||
[[Install]] the {{Pkg|iptables}} package. Use iptables to enable NAT: | [[Install]] the {{Pkg|iptables}} package. Use iptables to enable NAT: | ||
Line 74: | Line 76: | ||
{{Note|Of course, this also works with a mobile broadband connection (usually called ppp0 on routing PC).}} | {{Note|Of course, this also works with a mobile broadband connection (usually called ppp0 on routing PC).}} | ||
Use {{ic|-I DOCKER-USER}} instead of {{ic|-A FORWARD}} if you installed docker. [https://docs.docker.com/network/iptables/] | |||
# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE | |||
# iptables -I DOCKER-USER 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT | |||
# iptables -I DOCKER-USER 2 -i net0 -o internet0 -j ACCEPT | |||
If connected via PPPoE, clamp mss to pmtu in order to prevent fragmentation: | |||
# iptables -t mangle -A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu | |||
Read the [[iptables]] article for more information (especially saving the rule and applying it automatically on boot). There is also an excellent guide on iptables [[Simple stateful firewall]]. | Read the [[iptables]] article for more information (especially saving the rule and applying it automatically on boot). There is also an excellent guide on iptables [[Simple stateful firewall]]. | ||
==== With nftables ==== | |||
[[Install]] the {{Pkg|nftables}} package. To enable NAT with [[nftables]], you will have to create the {{ic|postrouting}} chain in a new/existing table: | |||
# nft add table inet nat | |||
# nft add chain inet nat postrouting '{ type nat hook postrouting priority 100 ; }' | |||
After that, you have to masquerade the {{ic|net0}} addresses for {{ic|internet0}}: | |||
# nft add rule inet nat postrouting oifname internet0 masquerade | |||
Many firewall configurations, like [https://gitlab.archlinux.org/archlinux/packaging/packages/nftables/-/blob/main/nftables.conf the default] {{ic|/etc/nftables.conf}}, set the default policy of the 'filter' table's 'forward' chain to 'drop'. In such cases, you will need rules to allow forwarding NAT traffic: | |||
# nft add rule inet filter forward ct state related,established accept | |||
# nft add rule inet filter forward iifname net0 oifname internet0 accept | |||
You can find more information on NAT in nftables in the [https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT) nftables Wiki]. If you want to make these changes permanent, follow the instructions on [[nftables]]. | |||
==== With firewalld ==== | |||
[[Install]] the {{Pkg|firewalld}} package. [[firewalld]] is a firewall daemon which relies on [[nftables]] or [[iptables]]. First change the firewalld zones of network interfaces: | |||
# firewall-cmd --zone=external --change-interface=internet0 --permanent | |||
# firewall-cmd --zone=internal --change-interface=net0 --permanent | |||
Then add a new policy to let traffic flow between the internal and external zone: | |||
# firewall-cmd --permanent --new-policy int2ext | |||
# firewall-cmd --permanent --policy int2ext --add-ingress-zone internal | |||
# firewall-cmd --permanent --policy int2ext --add-egress-zone external | |||
# firewall-cmd --permanent --policy int2ext --set-target ACCEPT | |||
# firewall-cmd --reload | |||
{{Tip|1=You can use stricter policy rules than bare {{ic|1=ACCEPT}} as illustrated in the {{ic|1=Firewall Rules}} section of the firewalld concept page[https://firewalld.org/documentation/concepts.html] | |||
For example, to allow only nodes in {{ic|192.168.2.0/24}} to access the internet, do: | |||
{{ic|1=firewall-cmd --permanent --policy int2ext --add-rich-rule='rule family=ipv4 source address=192.168.2.0/24 accept'}} | |||
Do not forget to reload rules afterwards: | |||
{{ic|1=firewall-cmd --reload}} | |||
}} | |||
=== Assigning IP addresses to the client PC(s) === | === Assigning IP addresses to the client PC(s) === | ||
If you are planning to regularly have several machines using the internet shared by this machine, then is a good idea to install a [[Wikipedia:DHCP|DHCP | If you are planning to regularly have several machines using the internet shared by this machine, then is a good idea to install a [[Wikipedia:DHCP|DHCP]] server. See [[Router#DNS and DHCP]] for the available options. Then configure a DHCP client on every client PC, see [[Network configuration#Network managers]]. | ||
{{Style|This is not an iptables guide. Expanding the chain with {{ic|iptables -I}} might skip other important rules; if you need to script an ON/OFF switch for this, use custom chain with a jump placed carefully in the INPUT chain.}} | {{Style|This is not an iptables guide. Expanding the chain with {{ic|iptables -I}} might skip other important rules; if you need to script an ON/OFF switch for this, use custom chain with a jump placed carefully in the INPUT chain.}} | ||
Incoming connections to UDP port 67 has to be allowed for DHCP server. It also necessary to allow incoming connections to UDP/TCP port 53 for DNS requests. | Incoming connections to UDP port 67 has to be allowed for DHCP server. It also necessary to allow incoming connections to UDP/TCP port 53 for DNS requests. | ||
# iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT | # iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT | ||
# iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT | # iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT | ||
# iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT | # iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT | ||
If you are not | Alternatively using [[firewalld]] | ||
# firewall-cmd --zone=internal --permanent --add-service dns | |||
# firewall-cmd --zone=internal --permanent --add-service dhcp | |||
# firewall-cmd --zone=internal --permanent --add-service dhcpv6 | |||
If you are not planning to use this setup regularly, you can manually add an IP to each client instead. | |||
==== Manually adding an IP ==== | ==== Manually adding an IP ==== | ||
Instead of using DHCP, | Instead of using DHCP, a static IP address and a default route via {{ic|192.168.123.100}} can also be configured manually. There are many tools available to configure the network accordingly. One prominent example of such a tool is {{man|8|ip}}, see [[Network configuration#Network management]]. Alternatively, one can use a {{ic|.network}} file, see [[Systemd-networkd#Wired adapter using a static IP]] to setup a static IP. | ||
Configure a DNS server for each client, see [[ | Configure a DNS server for each client, see [[Domain name resolution]] for details. | ||
That | That is it. The client PC should now have Internet. | ||
== Troubleshooting == | == Troubleshooting == | ||
If you are able to connect the two PCs but cannot send data (for example, if the client PC makes a DHCP request to the server PC, the server PC receives the request and offers an IP to the client, but the client does not accept it, timing out instead), check that you do not have other [[ | If you are able to connect the two PCs but cannot send data (for example, if the client PC makes a DHCP request to the server PC, the server PC receives the request and offers an IP to the client, but the client does not accept it, timing out instead), check that you do not have other [[iptables]] rules [https://bbs.archlinux.org/viewtopic.php?pid=1093208 interfering]. | ||
=== Clients cannot access the internet or cannot connect === | |||
Symptoms might also include: Clients get {{ic|host is down}} when pinging host, gets {{ic|no route to host}} when pinging devices outside the LAN (that should be forwarded by NAT), DHCP offers not crossing a bridge, ... | |||
It is known that [[docker]] may cause these problems. Simply [[disabling]] {{ic|docker.service}} and {{ic|docker.socket}} solves this problem. | |||
[https://github.com/moby/moby/issues/43719 docker github issue]. | |||
== See also == | == See also == | ||
* [ | |||
* [https://xyne.dev/notes/network/dhcp_with_dns.html Xyne's guide and scripts for launching a subnet with DHCP and DNS] | |||
* [[NetworkManager]] can be configured for internet sharing if used. | * [[NetworkManager]] can be configured for internet sharing if used. |
Latest revision as of 20:28, 16 January 2024
This article explains how to share the internet connection from one machine to other(s).
Requirements
The machine acting as server should have an additional network device. That network device requires a functional data link layer to the machine(s) that are going to receive internet access:
- To be able to share internet to several machines a switch can provide the data link layer connection.
- A wireless device can share access to several machines as well, see Software access point first for this case.
- If you are sharing to only one machine, a crossover cable is sufficient. In case one of the two computers' ethernet cards has MDI-X capability, a crossover cable is not necessary and a regular ethernet cable can be used. Executing
ethtool interface | grep MDI
as root helps to figure it.
Configuration
This section assumes that the network device connected to the client computer(s) is named net0
and the network device connected to the internet as internet0
.
All configuration is done on the server computer, except for the final step of #Assigning IP addresses to the client PC(s).
Static IP address
On the server computer, assign a static IPv4 address to the interface connected to the other machines. The first 3 bytes of this address cannot be exactly the same as those of another interface, unless both interfaces have netmasks strictly greater than /24.
# ip link set up dev net0 # ip addr add 192.168.123.100/24 dev net0 # arbitrary address
To have your static IP assigned at boot, you can use a network manager.
Enable packet forwarding
To check the current packet forwarding settings, run:
# sysctl -a | grep forward
You will note options for controlling forwarding per default, per interface, as well as separate options for IPv4/IPv6 per interface. For detailed description of all available options, see the kernel documentation.
To enable IPv4 and IPv6 packet forwarding, configure sysctl to set these settings:
net.ipv4.ip_forward = 1 net.ipv4.conf.all.forwarding = 1 net.ipv6.conf.all.forwarding = 1
net.ipv[46].conf.interface_name.forwarding=1
instead.IPForward=kernel
semantics introduced in a previous systemd release 220/221 to honor kernel settings does not apply anymore.[1] [2]To make changes persistent across reboots, see Sysctl#Configuration. You might consider writing settings to a file with a descriptive filename, such as /etc/sysctl.d/30-ipforward.conf
.
Afterwards it is advisable to double-check forwarding is enabled as required after a reboot.
Enable NAT
With iptables
Install the iptables package. Use iptables to enable NAT:
# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE # iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # iptables -A FORWARD -i net0 -o internet0 -j ACCEPT
Use -I DOCKER-USER
instead of -A FORWARD
if you installed docker. [3]
# iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE # iptables -I DOCKER-USER 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # iptables -I DOCKER-USER 2 -i net0 -o internet0 -j ACCEPT
If connected via PPPoE, clamp mss to pmtu in order to prevent fragmentation:
# iptables -t mangle -A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Read the iptables article for more information (especially saving the rule and applying it automatically on boot). There is also an excellent guide on iptables Simple stateful firewall.
With nftables
Install the nftables package. To enable NAT with nftables, you will have to create the postrouting
chain in a new/existing table:
# nft add table inet nat # nft add chain inet nat postrouting '{ type nat hook postrouting priority 100 ; }'
After that, you have to masquerade the net0
addresses for internet0
:
# nft add rule inet nat postrouting oifname internet0 masquerade
Many firewall configurations, like the default /etc/nftables.conf
, set the default policy of the 'filter' table's 'forward' chain to 'drop'. In such cases, you will need rules to allow forwarding NAT traffic:
# nft add rule inet filter forward ct state related,established accept # nft add rule inet filter forward iifname net0 oifname internet0 accept
You can find more information on NAT in nftables in the nftables Wiki. If you want to make these changes permanent, follow the instructions on nftables.
With firewalld
Install the firewalld package. firewalld is a firewall daemon which relies on nftables or iptables. First change the firewalld zones of network interfaces:
# firewall-cmd --zone=external --change-interface=internet0 --permanent # firewall-cmd --zone=internal --change-interface=net0 --permanent
Then add a new policy to let traffic flow between the internal and external zone:
# firewall-cmd --permanent --new-policy int2ext # firewall-cmd --permanent --policy int2ext --add-ingress-zone internal # firewall-cmd --permanent --policy int2ext --add-egress-zone external # firewall-cmd --permanent --policy int2ext --set-target ACCEPT # firewall-cmd --reload
ACCEPT
as illustrated in the Firewall Rules
section of the firewalld concept page[4]
For example, to allow only nodes in 192.168.2.0/24
to access the internet, do:
firewall-cmd --permanent --policy int2ext --add-rich-rule='rule family=ipv4 source address=192.168.2.0/24 accept'
Do not forget to reload rules afterwards:
firewall-cmd --reload
Assigning IP addresses to the client PC(s)
If you are planning to regularly have several machines using the internet shared by this machine, then is a good idea to install a DHCP server. See Router#DNS and DHCP for the available options. Then configure a DHCP client on every client PC, see Network configuration#Network managers.
Incoming connections to UDP port 67 has to be allowed for DHCP server. It also necessary to allow incoming connections to UDP/TCP port 53 for DNS requests.
# iptables -I INPUT -p udp --dport 67 -i net0 -j ACCEPT # iptables -I INPUT -p udp --dport 53 -s 192.168.123.0/24 -j ACCEPT # iptables -I INPUT -p tcp --dport 53 -s 192.168.123.0/24 -j ACCEPT
Alternatively using firewalld
# firewall-cmd --zone=internal --permanent --add-service dns # firewall-cmd --zone=internal --permanent --add-service dhcp # firewall-cmd --zone=internal --permanent --add-service dhcpv6
If you are not planning to use this setup regularly, you can manually add an IP to each client instead.
Manually adding an IP
Instead of using DHCP, a static IP address and a default route via 192.168.123.100
can also be configured manually. There are many tools available to configure the network accordingly. One prominent example of such a tool is ip(8), see Network configuration#Network management. Alternatively, one can use a .network
file, see Systemd-networkd#Wired adapter using a static IP to setup a static IP.
Configure a DNS server for each client, see Domain name resolution for details.
That is it. The client PC should now have Internet.
Troubleshooting
If you are able to connect the two PCs but cannot send data (for example, if the client PC makes a DHCP request to the server PC, the server PC receives the request and offers an IP to the client, but the client does not accept it, timing out instead), check that you do not have other iptables rules interfering.
Clients cannot access the internet or cannot connect
Symptoms might also include: Clients get host is down
when pinging host, gets no route to host
when pinging devices outside the LAN (that should be forwarded by NAT), DHCP offers not crossing a bridge, ...
It is known that docker may cause these problems. Simply disabling docker.service
and docker.socket
solves this problem.
See also
- Xyne's guide and scripts for launching a subnet with DHCP and DNS
- NetworkManager can be configured for internet sharing if used.