Author: | Francesco Poli |
---|---|
Contact: | invernomuto@paranoici.org |
Version: | 0.23 |
Copyright: | Expat license |
Notice: | Copyright (c) 2012-2024 Francesco Poli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
About this document | |
---|---|
Web form | HyperText Markup Language |
Source form | reStructuredText |
Web stylesheet | Cascading StyleSheets |
Build directives | Makefile |
In another document (HTML, reST) you saw how to install a Debian testing base system on a machine to be used as a network gateway/firewall/server. You also found references to other general workstation documents to follow in order to tune the system. Now it's time to begin shaping this machine for its primary purposes: being a network gateway and firewall.
Sometimes you need to copy data between different directories (or between network-connected machines). For simple cases, cp (or scp) may suffice. However, more complicated cases may require something more sophisticated; install the following package:
# aptitude install rsync
In order to enable the secondary network interface (the one that will be connected to the LAN switch), edit the configuration file for network interfaces, until it looks like:
# cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface allow-hotplug enp1s0 iface enp1s0 inet dhcp # The local network interface allow-hotplug enp2s0 iface enp2s0 inet static address 192.168.5.1/24
Then, edit the /etc/hosts configuration file, so that the first (IPv4) part becomes:
$ head -n 2 /etc/hosts 127.0.0.1 localhost 192.168.5.1 $HOSTNAME # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
where $HOSTNAME is the name that was previously chosen for the machine.
Issue the following command, if you want to immediately see the effects of the above configuration changes:
# ifup enp2s0
We want our machine to work as DHCP server and caching DNS proxy for the LAN connected to the secondary network interface (enp2s0). In order to achieve this result, install the following package:
# aptitude install dnsmasq
Then, edit the Dnsmasq configuration file /etc/dnsmasq.conf so that:
$ grep domain-needed /etc/dnsmasq.conf domain-needed $ grep bogus-priv /etc/dnsmasq.conf bogus-priv $ grep ^address= /etc/dnsmasq.conf address=/double-click.net/127.0.0.1 address=/doubleclick.net/127.0.0.1 address=/ad.doubleclick.net/127.0.0.1 address=/ad.ca.doubleclick.net/127.0.0.1 address=/adremote.timeinc.net/127.0.0.1 address=/google-analytics.com/127.0.0.1 address=/googlesyndication.com/127.0.0.1 address=/adsremote.scripps.net/127.0.0.1 address=/a.as-us.falkag.net/127.0.0.1 address=/interclick.com/127.0.0.1 address=/a1.interclick.com/127.0.0.1 address=/media.fastclick.net/127.0.0.1 address=/network.realmedia.com/127.0.0.1 address=/ads.auctionads.com/127.0.0.1 address=/ads.adbrite.com/127.0.0.1 $ grep ^interface= /etc/dnsmasq.conf interface=enp2s0 $ grep ^dhcp-range= /etc/dnsmasq.conf dhcp-range=192.168.5.100,192.168.5.199 $ grep bogus-nx /etc/dnsmasq.conf bogus-nxdomain=64.94.110.11 bogus-nxdomain=54.72.52.58 $ grep '^dhcp.*wpad' /etc/dnsmasq.conf dhcp-name-match=set:wpad-ignore,wpad dhcp-ignore-names=tag:wpad-ignore
and restart the daemon:
# systemctl restart dnsmasq.service
The following DHCP client should be already installed (and not marked as automatically installed):
# aptitude search '~i dhcp' i dhcpcd-base - DHCPv4 and DHCPv6 dual-stack client (binar
Create the following configuration file:
# echo 'nameserver 127.0.0.1' > /etc/resolv.conf.head
in order to use the DNS cache provided by Dnsmasq on the gateway box itself, as well as on the local network.
If these packages are installed, you may purge them:
# aptitude --purge-unused purge isc-dhcp-client isc-dhcp-common
In order to enable this configuration change, take down and up the primary network interface:
# ifdown enp1s0 ; ifup enp1s0
We want the clock of our machine to be as accurate as possible. Install the following NTP client and server:
# aptitude install chrony
Then, edit its configuration file /etc/chrony/chrony.conf so that:
$ grep ^pool /etc/chrony/chrony.conf pool 2.debian.pool.ntp.org iburst minpoll 10 maxpoll 12 $ grep '^log ' /etc/chrony/chrony.conf log tracking measurements statistics $ grep -B 2 ^makestep /etc/chrony/chrony.conf # Step the system clock instead of slewing it if the adjustment is larger than # 200 seconds, but only in the first three clock updates. makestep 200 3 $ grep -B 1 ^allow /etc/chrony/chrony.conf # Allow local clients to connect to this server. allow 192.168/16
and restart the daemon:
# systemctl restart chrony.service
We want our machine to act as a firewall and NAT (Network Address Translator). First of all, add this configuration file:
# cat > /etc/sysctl.d/99-local-gateway.conf << EOF net.ipv4.conf.default.rp_filter=1 net.ipv4.conf.all.rp_filter=1 net.ipv4.ip_forward=1 EOF
You can apply these settings immediately with the following command:
# sysctl --system
They will however be applied automatically from the next reboot.
The following firewall command line tool should be already installed (and not marked as automatically installed):
# aptitude search '~i ^nftables' i nftables - Program to control packet filtering rules
Prepare the following configuration file:
$ cat nftables.conf #!/usr/sbin/nft -f flush ruleset define wan = enp1s0 # interface to the public insecure net define lan = enp2s0 # interface to the local net to be protected table inet nat { chain POSTROUTING { type nat hook postrouting priority srcnat; policy accept; # masquerade everything going out to the public net oifname $wan counter masquerade } } table inet filter { chain base_checks { # allow established valid connections ct state invalid counter drop ct state established,related counter accept # always allow pinging ip protocol icmp counter accept meta l4proto ipv6-icmp counter accept # always reject connections to identd (see Securing Debian manual FAQ) tcp dport "auth" counter reject } chain INPUT { type filter hook input priority filter; policy drop; jump base_checks # accept locally generated traffic from loopback interface iifname "lo" counter accept # rules for traffic coming from the public net iifname $wan counter jump wan_in # rules for traffic coming from the local net iifname $lan counter jump lan_in } chain FORWARD { type filter hook forward priority filter; policy drop; jump base_checks # rules for traffic passing from the local net to the public net iifname $lan oifname $wan counter jump lan_to_wan # rules for traffic passing from the public net to the local net iifname $wan oifname $lan counter jump wan_to_lan } chain OUTPUT { type filter hook output priority filter; policy drop; jump base_checks # accept locally generated traffic to loopback interface oifname "lo" counter accept # rules for traffic going to the public net oifname $wan counter jump wan_out # rules for traffic going to the local net oifname $lan counter jump lan_out } chain lan_in { # local services accessible from the local net tcp dport "ssh" counter accept udp dport { "domain", "bootps" } \ counter accept # log packets that failed to be accepted limit rate 3/hour burst 5 packets counter log level debug } chain lan_out { # local net remote services accessible from the local system udp dport "bootpc" counter accept # log packets that failed to be accepted limit rate 3/hour burst 5 packets counter log } chain lan_to_wan { # public net remote services accessible from the local net tcp dport { "ftp", "ftps", "http", "https", "http-alt", \ "ssh", "hkp", "smtp", "submissions", \ "submission", "pop3", "pop3s", "dict", "ircd", \ "git", "whois" } \ counter accept udp dport "ntp" counter accept # public net radio/video streams accessible from the local net tcp dport { 11590, 8000, 8294 } \ counter accept # public net remote proxy services accessible from the local net tcp dport 8888 counter accept # public net remote media (audio/video) services accessible # from the local net # (for Google meet) udp dport 19302-19309 counter accept # (for Microsoft teams) udp dport 3478-3481 counter accept # log packets that failed to be accepted limit rate 3/hour burst 5 packets counter log } chain wan_in { # local services for which access from the public net # will be denied, without even logging connection attempts # epmap Microsoft end-point mapper # 137-139 NetBIOS noise # microsoft-ds Windows Share attacks # ms-sql-s Microsoft SQL Server # 2967 Symantec overflow attacks tcp dport { "epmap", 137-139, "microsoft-ds", "ms-sql-s", 2967 } \ counter drop # 67-68 bootps & bootpc (for DHCP) # 137-139 NetBIOS noise # ipp Internet Printing Protocol # 1025-1031 so-called "WinPopUP spam" # ms-sql-s Microsoft SQL Server # 2222 MS-Office for MacOSX antipiracy udp dport { 67-68, 137-139, "ipp", 1025-1031, "ms-sql-s", 2222 } \ counter drop # make ssh service accessible from the public net # (enable only when needed...) # tcp dport "ssh" counter accept # log packets that weren't dropped (yet) or accepted limit rate 3/hour burst 5 packets counter log level debug } chain wan_out { # public net remote services accessible from the local system tcp dport { "ftp", "ftps", "http", "https", "http-alt", "hkp" } \ counter accept udp dport { "domain", "bootps", "ntp" } \ counter accept # log packets that failed to be accepted limit rate 3/hour burst 5 packets counter log } chain wan_to_lan { # log packets that failed to be accepted limit rate 3/hour burst 5 packets counter log level err } } table inet helpers { # make ftp service properly accessible ct helper ftp-standard { type "ftp" protocol tcp } chain PREROUTING { type filter hook prerouting priority filter; tcp dport "ftp" ct helper set "ftp-standard" } }
You may want to check its syntax:
# nft -c -f ./nftables.conf
If you want to test this firewall ruleset, you can do so by issuing the following command:
# nft -f ./nftables.conf
If you're satisfied with the result, you can copy this new ruleset to the configuration file that the systemd service expects to load:
# install -m 744 ./nftables.conf /etc/nftables.conf
In order to load this ruleset at boot, enable the systemd service:
# systemctl enable nftables.service
In order to load the ruleset defined in /etc/nftables.conf:
# systemctl start nftables.service
To reload the ruleset defined in /etc/nftables.conf:
# systemctl reload nftables.service
To flush the ruleset, you may use the following command:
# systemctl stop nftables.service
The syntax is explained in the following man page:
$ man nft
If you already have firewall rules set with iptables-legacy, you should flush them, since they do not easily coexist with the rules set with nft. In order to migrate from the previous firewall configuration based on iptables-legacy to a new one based on nft, you may use a machine-translated ruleset as a starting point for the nftables.conf configuration file you are going to manually write:
# iptables-legacy-save > /tmp/iptables.txt # iptables-restore-translate -f /tmp/iptables.txt > /tmp/nft.txt
Then flush all the rules based on iptables-legacy. For instance, if you were using ferm, issue the command:
# systemctl disable --now ferm.service
At this point load the translated rules with nft and obtain a first draft version of nftables.conf:
# nft flush ruleset # nft -f /tmp/nft.txt # echo '#!/usr/sbin/nft -f' > nftables.conf # echo 'flush ruleset' >> nftables.conf # nft -s -S list ruleset >> nftables.conf
Now you have a preliminary version of nftables.conf, which needs to be heavily refined by hand, before it becomes something like the one shown above. Once you are satisfied with the new firewall configuration, you may purge any package that you were using to manage the iptable-legacy rules (for instance, ferm).
Now the machine is ready to behave as a network gateway and firewall. But it could also be useful as a print server. More details in a separate document (HTML, reST).