https://wiki.archlinux.org/api.php?action=feedcontributions&user=Branch&feedformat=atomArchWiki - User contributions [en]2024-03-29T12:42:21ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Sysctl&diff=422169Sysctl2016-02-25T03:46:56Z<p>Branch: /* Configuration */ reflect move of /proc/sys/net/bridge/* to br_netfilter module</p>
<hr />
<div>{{Lowercase title}}<br />
[[Category:Kernel]]<br />
[[ja:Sysctl]]<br />
[[Wikipedia:sysctl|sysctl]] is a tool for examining and changing [[kernel parameters]] at runtime (package {{Pkg|procps-ng}} in [[official repositories]]). sysctl is implemented in procfs, the virtual process file system at {{ic|/proc/}}.<br />
<br />
== Configuration ==<br />
<br />
{{Note|From version 207 and 21x, [[systemd]] only applies settings from {{Ic|/etc/sysctl.d/*.conf}} and {{Ic|/usr/lib/sysctl.d/*.conf}}. If you had customized {{Ic|/etc/sysctl.conf}}, you need to rename it as {{Ic|/etc/sysctl.d/99-sysctl.conf}}. If you had e.g. {{Ic|/etc/sysctl.d/foo}}, you need to rename is to {{Ic|/etc/sysctl.d/foo.conf}}.}}<br />
<br />
The '''sysctl''' preload/configuration file can be created at {{Ic|/etc/sysctl.d/99-sysctl.conf}}. For [[systemd]], {{Ic|/etc/sysctl.d/}} and {{Ic|/usr/lib/sysctl.d/}} are drop-in directories for kernel sysctl parameters. The naming and source directory decide the order of processing, which is important since the last parameter processed may override earlier ones. For example, parameters in a {{ic|/usr/lib/sysctl.d/50-default.conf}} will be overriden by equal parameters in {{ic|/etc/sysctl.d/50-default.conf}} and any configuration file processed later from both directories. <br />
<br />
To load all configuration files manually, execute <br />
# sysctl --system <br />
which will also output the applied hierarchy. A single parameter file can also be loaded explicitly with <br />
# sysctl -p ''filename.conf''<br />
<br />
See [http://0pointer.de/blog/projects/the-new-configuration-files the new configuration files] and more specifically [http://0pointer.de/public/systemd-man/sysctl.d.html systemd's sysctl.d man page] for more information.<br />
<br />
The parameters available are those listed under {{Ic|/proc/sys/}}. For example, the {{Ic|kernel.sysrq}} parameter refers to the file {{Ic|/proc/sys/kernel/sysrq}} on the file system. The {{Ic|sysctl -a}} command can be used to display all currently available values.<br />
<br />
{{Note|If you have the kernel documentation installed ({{Pkg|linux-docs}}), you can find detailed information about sysctl settings in {{Ic|/usr/lib/modules/$(uname -r)/build/Documentation/sysctl/}}. It is highly recommended reading these before changing sysctl settings.}}<br />
<br />
Settings can be changed through file manipulation or using the {{Ic|sysctl}} utility. For example, to temporarily enable the [[Wikipedia:Magic_SysRq_key|magic SysRq key]]:<br />
<br />
# sysctl kernel.sysrq=1<br />
<br />
or:<br />
<br />
# echo "1" > /proc/sys/kernel/sysrq<br />
<br />
To preserve changes between reboots, add or modify the appropriate lines in {{Ic|/etc/sysctl.d/99-sysctl.conf}} or another applicable parameter file in {{Ic|/etc/sysctl.d/}}.<br />
{{Tip|Some parameters that can be applied may depend on kernel modules which in turn might not be loaded. For example parameters in {{ic|/proc/sys/net/bridge/*}} depend on the {{ic|br_netfilter}} module. If it is not loaded at runtime (or after a reboot), those will ''silently'' not be applied. See [[Kernel modules#Loading]]}}<br />
<br />
== Security ==<br />
<br />
See [[Security#Kernel hardening]].<br />
<br />
== Networking ==<br />
<br />
=== Improving performance ===<br />
<br />
{{Warning|This may cause dropped frames with load-balancing and NATs, only use this for a server that communicates only over your local network.}}<br />
<br />
# reuse/recycle time-wait sockets<br />
net.ipv4.tcp_tw_reuse = 1<br />
net.ipv4.tcp_tw_recycle = 1<br />
<br />
=== TCP/IP stack hardening ===<br />
<br />
The following specifies a parameter set to tighten network security options of the kernel for the IPv4 protocol and related IPv6 parameters where an equivalent exists. <br />
<br />
For some usecases, for example using the system as a [[router]], other parameters may be useful or required as well. <br />
<br />
{{bc|1=<br />
#### ipv4 networking and equivalent ipv6 parameters ####<br />
<br />
## TCP SYN cookie protection (default)<br />
## helps protect against SYN flood attacks<br />
## only kicks in when net.ipv4.tcp_max_syn_backlog is reached<br />
net.ipv4.tcp_syncookies = 1<br />
<br />
## protect against tcp time-wait assassination hazards<br />
## drop RST packets for sockets in the time-wait state<br />
## (not widely supported outside of linux, but conforms to RFC)<br />
net.ipv4.tcp_rfc1337 = 1<br />
<br />
## sets the kernels reverse path filtering mechanism to value 1(on)<br />
## will do source validation of the packet's recieved from all the interfaces on the machine<br />
## protects from attackers that are using ip spoofing methods to do harm<br />
net.ipv4.conf.all.rp_filter = 1<br />
net.ipv6.conf.all.rp_filter = 1<br />
<br />
## tcp timestamps<br />
## + protect against wrapping sequence numbers (at gigabit speeds)<br />
## + round trip time calculation implemented in TCP<br />
## - causes extra overhead and allows uptime detection by scanners like nmap<br />
## enable @ gigabit speeds<br />
net.ipv4.tcp_timestamps = 0<br />
#net.ipv4.tcp_timestamps = 1<br />
<br />
## log martian packets<br />
net.ipv4.conf.all.log_martians = 1<br />
<br />
## ignore echo broadcast requests to prevent being part of smurf attacks (default)<br />
net.ipv4.icmp_echo_ignore_broadcasts = 1<br />
<br />
## ignore bogus icmp errors (default)<br />
net.ipv4.icmp_ignore_bogus_error_responses = 1<br />
<br />
## send redirects (not a router, disable it)<br />
net.ipv4.conf.all.send_redirects = 0<br />
<br />
## ICMP routing redirects (only secure)<br />
#net.ipv4.conf.all.secure_redirects = 1 (default)<br />
net.ipv4.conf.default.accept_redirects=0<br />
net.ipv4.conf.all.accept_redirects=0<br />
net.ipv6.conf.default.accept_redirects=0<br />
net.ipv6.conf.all.accept_redirects=0<br />
}}<br />
<br />
== Virtual memory ==<br />
<br />
There are several key parameters to tune the operation of the virtual memory (VM) subsystem of the Linux kernel and the writeout of dirty data to disk. See the [https://www.kernel.org/doc/Documentation/sysctl/vm.txt Linux kernel documentation] for more information.<br />
<br />
{{bc|1=<br />
# Contains, as a percentage of total system memory, the number of pages at which<br />
# a process which is generating disk writes will start writing out dirty data.<br />
vm.dirty_ratio = 3<br />
<br />
# Contains, as a percentage of total system memory, the number of pages at which<br />
# the background kernel flusher threads will start writing out dirty data.<br />
vm.dirty_background_ratio = 2<br />
}}<br />
<br />
As noted in the comments, one needs to consider the total amount of RAM when setting these values. <br />
<br />
* {{ic|vm.dirty_ratio}} defaults to 10 (percent of RAM). Consensus is that 10% of RAM when RAM is say half a GB (so 10% is ~50 MB) is a sane value on spinning disks, but it can be MUCH worse when RAM is larger, say 16 GB (10% is ~1.6 GB), as that's several seconds of writeback on spinning disks. A more sane value in this case is 3 (16*0.03 ~ 491 MB).<br />
<br />
* {{ic|vm.dirty_background_ratio}} similarly, 5 (% of RAM) by default may be just fine for small memory values, but again, consider and adjust accordingly for the amount of RAM on a particular system.<br />
<br />
== MDADM ==<br />
<br />
When the kernel performs a resync operation of a software raid device it tries not to create a high system load by restricting the speed of the operation. Using sysctl it is possible to change the lower and upper speed limit.<br />
<br />
{{bc|1=<br />
# Set maximum and minimum speed of raid resyncing operations<br />
dev.raid.speed_limit_max = 10000<br />
dev.raid.speed_limit_min = 1000<br />
}}<br />
<br />
If mdadm is compiled as a module {{ic|md_mod}}, the above settings are available only after the module has been loaded. If the settings shall be loaded on boot via {{ic|/etc/sysctl.d}}, the module {{ic|md_mod}} may be loaded beforehand through {{ic|/etc/modules-load.d}}.<br />
<br />
== Troubleshooting ==<br />
<br />
=== Small periodic system freezes ===<br />
<br />
Set dirty bytes to small enough value (for example 4M):<br />
<br />
vm.dirty_background_bytes = 4194304<br />
vm.dirty_bytes = 4194304<br />
<br />
Try to change {{ic|kernel.io_delay_type}} (x86 only):<br />
* 0 - IO_DELAY_TYPE_0X80<br />
* 1 - IO_DELAY_TYPE_0XED<br />
* 2 - IO_DELAY_TYPE_UDELAY<br />
* 3 - IO_DELAY_TYPE_NONE<br />
<br />
== See also ==<br />
<br />
* The [http://linux.die.net/man/8/sysctl sysctl(8)] and [http://www.unixlore.net/cgi-bin/man/man2html?5+sysctl.conf sysctl.conf(5)] man pages<br />
* Linux kernel documentation ({{Ic|<kernel source dir>/Documentation/sysctl/}})<br />
* Kernel Documentation: [https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt IP Sysctl]<br />
* SysCtl.conf Tweaked for Security and Cable Speed [http://blog.gotux.net/code/config/sysctl/]{{Dead link|2015|12|14}}<br />
* Kernel network parameters for sysctl [http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.kernel.html]</div>Branchhttps://wiki.archlinux.org/index.php?title=Router&diff=337060Router2014-09-24T04:48:27Z<p>Branch: /* Acquiring WAN IPv6 via DHCPv6-PD */ dhcpcd.conf - explicitely assign iaid as default has changed</p>
<hr />
<div>[[Category:Networking]]<br />
[[Category:Security]]<br />
This article is a tutorial for turning a computer into an internet gateway/router. It focuses on ''security'', since the gateway is connected directly to the Internet. It should not run '''any''' services available to the outside world. Towards the LAN, it should only run gateway specific services. It should not run httpd, ftpd, samba, nfsd, etc. as those belong on a server in the LAN as they introduce security flaws.<br />
<br />
This article does not attempt to show how to set up a shared connection between 2 PCs using cross-over cables. For a simple internet sharing solution, see [[Internet sharing]].<br />
<br />
==Hardware Requirements==<br />
* At least 1 GB of hard drive space. The base install will take up around 500MB of space and if you want to use a caching web proxy, you will need to reserve space for the cache as well.<br />
* At least two physical network interfaces: a gateway connects two networks with each other. You will need to be able to connect those networks to the same physical computer. One interface must connect to the external network, while the other connects to the internal network.<br />
* A hub, switch or UTP cable: You need a way to connect the other computers to the gateway<br />
<br />
==Conventions==<br />
Conventions in this guide will be to use non-realistic interface names, to avoid confusion about which interface is which.<br />
<br />
* '''intern0''': the network card connected to the LAN. On an actual computer it will probably have the name enp2s0, enp1s1, etc.<br />
* '''extern1''': the network card connected to the external network (or WAN). It will probably have the name enp2s0, enp1s1, etc.<br />
<br />
==Installation==<br />
{{Note | For a full installation guide, see the [[Installation guide]].}}<br />
<br />
A fresh install of Arch Linux is the easiest to start from, as no configuration changes have been made and there is a minimal amount of packages installed. This is helpful when attempting to reduce security risk.<br />
<br />
===Partitioning===<br />
<br />
For security purposes, {{ic|/var}}, {{ic|/tmp}} and {{ic|/home}} should be separate from the {{ic|/}} partition. This prevents disk space from being completely used up by log files, daemons or the unprivileged user. It also allows different mount options for those partitions. If you have already partitioned your drive, the [http://gparted.sourceforge.net/ gparted livecd] can be used to resize, move, or create new partitions.<br />
<br />
Your home and root partitions can be much smaller than a regular install since this is not a desktop machine. {{ic|/var}} should be the largest partition—it is where databases, logs and long-term caches are stored. If you have a lot of RAM, mounting {{ic|/tmp}} as {{ic|tmpfs}} is a good idea, so making a disk partition for it during the initial install is unnecessary. Note that {{ic|/tmp}} is mounted as {{ic|tmpfs}} by default in Arch.<br />
<br />
===Post-Installation===<br />
After creation of non-root account you are recommended to install [[sudo]] and [[sudo#Disable root login|disable root login]].<br />
<br />
==Network interface configuration==<br />
<br />
===Persistent naming and Interface renaming===<br />
Systemd automatically chooses unique interface names for all your interfaces. These are persistent and will not change when you reboot. If you would like to rename interface to user friendlier names read [[Network configuration#Device_names]].<br />
<br />
===IP configuration===<br />
Now you will need to configure the network interfaces. The best way to do so is using [[netctl]] profiles. You will need to create two profiles.<br />
{{Note|If you will be connecting to the Internet only via PPPoE (you have one WAN port) you '''do not need''' to setup or enable the extern0-profile. See below for more information on configuring PPPoE.}}<br />
* {{ic|/etc/netctl/extern0-profile}}<br />
Description='Public Interface.'<br />
Interface=extern0<br />
Connection=ethernet<br />
IP='dhcp'<br />
<br />
* {{ic|/etc/netctl/intern0-profile}}<br />
Description='Private Interface'<br />
Interface=intern0<br />
Connection=ethernet<br />
IP='static'<br />
Address=('10.0.0.1/24')<br />
<br />
{{Note|The example configuration above assumes a full subnet. If you are building the gateway for a small amount of people, you will want to change the CIDR suffix to accommodate a smaller range. For example /27 will give you 10.0.0.1 to 10.0.0.30. You can find many CIDR calculators online.}}<br />
<br />
Next up is to set up the interfaces with netctl.<br />
# netctl enable extern0-profile<br />
# netctl enable intern0-profile<br />
<br />
==ADSL connection/PPPoE==<br />
Using rp-pppoe, we can connect an ADSL modem to the extern1 of the firewall and have Arch manage the connection. Make sure you put the modem in ''bridged'' mode though (either half-bridge or RFC1483), otherwise the modem will act as a router too.<br />
# pacman -S rp-pppoe<br />
<br />
It should be noted that if you use only PPPoE to connect to the internet (ie. you do not have other WAN port, except for the one that connects to your modem) you do not need to set up the {{ic|extern0-profile}} as the external pseudo-interface will be ppp0.<br />
<br />
===PPPoE configuration===<br />
You can use netctl to setup the pppoe connection. To get started<br />
# cp /etc/netctl/examples/pppoe /etc/netctl/<br />
and start editing. For the interface configuration choose the interface that connects to the modem. If you only connect to the internet through PPPoE this will probably be {{ic|extern0}}. Fill in the rest of the fields with your ISP information. See the pppoe section in netctl.profile man page for more information on the fields.<br />
<br />
==DNS and DHCP==<br />
We will use [[dnsmasq]], a DNS and DHCP daemon for the LAN. It was specifically designed for small sites. To get it, [[Pacman | install]] {{Pkg|dnsmasq}} from the [[official repositories]].<br />
<br />
Dnsmasq needs to be configured to be a DHCP server. To do this:<br />
<br />
Edit {{ic|/etc/dnsmasq.conf}}:<br />
<br />
interface=intern0 # make dnsmasq listen for requests only on intern0 (our LAN)<br />
expand-hosts # add a domain to simple hostnames in /etc/hosts<br />
domain=foo.bar # allow fully qualified domain names for DHCP hosts (needed when<br />
# "expand-hosts" is used)<br />
dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # defines a DHCP-range for the LAN: <br />
# from 10.0.0.2 to .255 with a subnet mask of 255.255.255.0 and a<br />
# DHCP lease of 1 hour (change to your own preferences)<br />
<br />
Somewhere below, you will notice you can also add "static" DHCP leases, i.e. assign an IP-address to the MAC-address of a computer on the LAN. This way, whenever the computer requests a new lease, it will get the same IP. That is very useful for network servers with a DNS record. You can also deny certain MAC's from obtaining an IP.<br />
<br />
Now start dnsmasq:<br />
# systemctl start dnsmasq.service<br />
<br />
==Connection sharing==<br />
<br />
Time to tie the two network interfaces to each other.<br />
===iptables===<br />
[[Simple stateful firewall]] documents the setup of an [[iptables]] firewall and NAT.<br />
<br />
Make sure you added the firewall exceptions for DHCP and Domain, if you want to use Dnsmasq:<br />
<br />
* Insert Rules:<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 53 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 53 -j ACCEPT<br />
<br />
<br />
===Shorewall===<br />
Shorewall, an iptables frontend, can be used as an easier alternative. See [[Shorewall]] for detailed configuration.<br />
<br />
==IPv6==<br />
<br />
{{Merge|IPv6|Merge into the main article, the topic is not specific to ''router configuration''. The wording should be probably changed along the way.}}<br />
<br />
''Useful reading: [[IPv6]] and the [https://en.wikipedia.org/wiki/IPv6 Wikipedia IPv6 entry].''<br />
<br />
You can use your router in IPv6 mode even if you do not have an IPv6 address from your ISP. Unless you disable IPv6 all interfaces should have been assigned a unique {{ic|fe80::/10}} address.<br />
<br />
For internal networking the block {{ic|fc00::/7}} has been reserved. These addresses are guaranteed to be unique and non-routable from the open internet. Addresses that belong to the {{ic|fc00::/7}} block are called [http://en.wikipedia.org/wiki/Unique_local_address Unique Local Addresses]. To get started [http://www.simpledns.com/private-ipv6.aspx generate a ULA /64 block] to use in your network. For this example we will use {{ic|fd00:aaaa:bbbb:cccc::/64}}. Firstly we must assign a static IPv6 on the internal interface. Modify the {{ic|intern0-profile}} we created above to include the following line<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::1/64 dev intern0')<br />
This will add the ULA to the internal interface. As far as the router goes, this is all you need to configure.<br />
<br />
===Router Advertisement and Stateless Autoconfiguration (SLAAC)===<br />
<br />
To properly hand out IPv6s to the network clients we will need to use an advertising daemon. The standard tool for this job is {{Pkg|radvd}} and is available in [[official repositories]]. Configuration of radvd is fairly simple. Edit {{ic|/etc/radvd.conf}} to include<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
The above configuration will tell clients to autoconfigure themselves using addresses from the specified /64 block. Addresses on the clients are uniquely generated using the MAC address of the connected interface and are optionally mangled for security reasons if [[IPv6#Privacy_Extensions|privacy extensions]] are enabled (which is recommended to do). On the client side you need to enable {{ic|1=IP6=stateless}} in your active netctl profile. If you want a static IP as well add<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::2/64 dev eth0')<br />
<br />
Don't forget to enable radvd.service<br />
<br />
====Firewall tweaks====<br />
<br />
Stateless autoconfiguration works on the condition that IPv6 icmp packets are allowed throughout the network. So some firewall tweaks are required on both ends of the network for it to work properly. On the '''client side''' all you need to do is allow the {{ic|ipv6-icmp}} protocol on the INPUT chain. If you are using [[Simple stateful firewall]] you only need to add<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
<br />
You can limit it to internal network using {{ic|-s fd00:aaaa:bbbb:cccc::/64}} and/or {{ic|-s fe80::/10}} if you feel it is a security threat. Additionally you must add the same rules to your router firewall but extending it to the OUTPUT and FORWARD chains as well.<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
-A OUTPUT -p ipv6-icmp -j ACCEPT<br />
-A FORWARD -p ipv6-icmp -j ACCEPT<br />
<br />
Again, you can limit it to the internal network for the INPUT chain.<br />
<br />
{{Expansion|More information on IPv6 firewalls required}}<br />
{{Expansion|Additional info on running DHCPv6 server instead of SLAAC}}<br />
<br />
===Global Unicast Addresses===<br />
<br />
====Static WAN IPv6====<br />
<br />
If your ISP or WAN network can access the IPv6 Internet you can assign global link addresses to your router and propagate them through SLAAC to your internal network. If you can use a Static IPv6 all you must do is add it to your external profile and enable it the advertisement of the global unicast block in {{ic|radvd.conf}}.<br />
<br />
In {{ic|/etc/netctl/extern0-profile}} simply add the IPv6 and the IPv6 prefix (usually /64) you have been provided<br />
<br />
IPCustom=('-6 addr add 2002:1:2:3:4:5:6:7/64 dev extern0')<br />
<br />
and edit {{ic|/etc/radvd.conf}} to include the new advertisement block.<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
prefix 2002:1:2:3::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
In that way your internal network clients will also get a Global IPv6 address. This IP is routable from the open internet, so adjust your firewalls. Please note that global and local IPv6s can co-exist on the same interface without further configuration.<br />
<br />
====Acquiring WAN IPv6 via DHCPv6-PD====<br />
<br />
If your ISP handles out IPv6s using [[wikipedia:Prefix_delegation|DHCPv6-PD]] you will need to use a DHCPv6 client to get the IP from your ISP. Common such programs are {{AUR|dibbler}}, {{AUR|wide-dhcpv6}} and {{Pkg|dhcpcd}}. ISC's {{Pkg|dhclient}} should also work, but documentation on prefix delegation is scarce.<br />
<br />
For '''dibbler''' edit {{ic|/etc/dibbler/client.conf}}<br />
<br />
log-mode short<br />
log-level 7<br />
iface "extern0" {<br />
ia<br />
pd<br />
}<br />
<br />
{{Tip|Read manpage '''{{ic|dibbler-client(8)}}''' for more information.}}<br />
<br />
For '''wide-dhcpv6''' edit {{ic|/etc/wide-dhcpv6/dhcp6c.conf}}<br />
<br />
interface extern0 {<br />
send ia-pd 0;<br />
};<br />
<br />
id-assoc pd 0 {<br />
prefix-interface intern0 {<br />
sla-id 1;<br />
sla-len 8;<br />
};<br />
};<br />
<br />
{{Note|1={{ic|sla-len}} should be set so that {{ic|1=(WAN-prefix) + (sla-len) = 64}}. In this case it is set up for a {{ic|/56}} prefix 56+8=64. For a {{ic|/64}} prefix {{ic|sla-len}} should be {{ic|0}}.}}<br />
<br />
To enable/start wide-dhcpv6 client use the command<br />
# systemctl enable/start dhcp6c@extern0.service<br />
<br />
{{Tip|Read manpages '''{{ic|dhcp6c(8)}}''' and '''{{ic|dhcp6c.conf(5)}}''' for more information.}}<br />
<br />
For '''dhcpcd''' edit {{ic|/etc/dhcpcd.conf}}. You might already be using dhcpcd for IPv4 so just update your existing configuration. If you would like to use it for IPv6 only uncomment the third line.<br />
<br />
duid<br />
noipv6rs<br />
waitip 6<br />
#ipv6only<br />
interface extern0<br />
iaid 1<br />
ia_pd 1/::/64 intern0/0/64<br />
<br />
This configuration will ask for a prefix from WAN (interface {{ic|extern0}}) and delegate it to the internal interface ({{ic|intern0}}).<br />
<br />
Because this configuration will neither solicit nor accept router advertisements no default route will be set. The kernel IPv6 stack can be allowed to set a dynamic default route with:<br />
<br />
sysctl -w net.ipv6.conf.extern0.accept_ra=2<br />
<br />
Or to have it persist after reboot:<br />
<br />
echo net.ipv6.conf.extern0.accept_ra = 2 > /etc/sysctl.d/80-ipv6dynroute.conf<br />
<br />
{{Tip|Also read: manpages '''{{ic|dhcpcd(8)}}''' and '''{{ic|dhcpcd.conf(5)}}'''.}}<br />
<br />
Because the IPv6 prefix is now dynamic, we need to change radvd to advertize any subnet instead of specific ones. With this configuration radvd will pick any /64 prefix available on the internal interface and propagate SLAAC IPv6s to the clients. Simply change {{ic|/etc/radvd.conf}} to<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix ::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
DeprecatePrefix on;<br />
};<br />
};<br />
<br />
====PPPoE and IPv6====<br />
If your ISP provides IPv6 via PPPoE you can enable it in your pppoe netctl profile. Just add this to pppoe netctl profile<br />
<br />
PPPoEIP6=yes<br />
<br />
and restart it. Also you must change any {{ic|extern0}} references to the configuration files above to {{ic|ppp0}} instead since IPv6 is assigned to ppp pseudo-interface instead of a real ethernet interface. Please note, that depending on your modem IPv6 might not be available through half-bridge so switch to full RFC1483 bridging instead.<br />
<br />
{{Warning|dhclient does not support DHCP6-PD via PPP}}<br />
<br />
==Cleanup==<br />
<br />
Now that the installation has been performed, it is necessary to remove as many packages as possible. Since we are making a gateway, keeping unneeded packages only "bloats" the system, and increases the number of security risks.<br />
<br />
First, check for obsolete/deprecated packages (likely after a fresh install and massive series of updates):<br />
<br />
$ pacman -Qm<br />
<br />
Review the list of explicitly installed packages that are not dependencies and remove any that are unneeded. Having only needed packages installed is an important security consideration.<br />
<br />
$ pacman -Qet<br />
<br />
Completely remove the packages you do not need along with their configuration files and dependencies:<br />
<br />
# pacman -Rsn package1 package2 package3<br />
<br />
== Logrotate ==<br />
<br />
You should review the [[logrotate]] configuration to make sure the box is not brought down by lack of diskspace due to logging.<br />
<br />
Logrotate is installed by default, so you will not have to install it.<br />
<br />
==Optional additions==<br />
<br />
===UPnP===<br />
The above configuration of shorewall does not include [[Wikipedia:UPnP|UPnP]] support. Use of UPnP is discouraged as it may make the gateway vulnerable to attacks from within the LAN. However, some applications require this to function correctly.<br />
<br />
To enable UPnP on your router, you need to install an UPnP Internet gateway daemon (IGD). To get it, install {{Pkg|miniupnpd}} from the [[official repositories]].<br />
<br />
Read the [http://www.shorewall.net/UPnP.html Shorewall guide on UPnP] for more information<br />
<br />
===Remote administration===<br />
<br />
[[SSH|OpenSSH]] can be used to administer your router remotely. This is useful for running it "headless" (no monitor or input devices).<br />
<br />
=== Caching web proxy ===<br />
<br />
See [[Squid]] or [[Polipo]] for the setup of a web proxy to speed up browsing and/or adding an extra layer of security.<br />
<br />
=== Time server ===<br />
To use the router as a time server, see [[Network Time Protocol daemon]].<br />
<br />
Then, configure shorewall or iptables to allow NTP traffic in and out.<br />
<br />
=== Content filtering ===<br />
<br />
Install and configure [[DansGuardian]] or [[Privoxy]] if you need a content filtering solution.<br />
<br />
=== Traffic shaping ===<br />
<br />
Traffic shaping is very useful, especially when you are not the only one on the LAN. The idea is to assign a priority to different types of traffic. Interactive traffic (ssh, online gaming) probably needs the highest priority, while P2P traffic can do with the lowest. Then there is everything in between.<br />
<br />
==== Traffic shaping with shorewall ====<br />
<br />
Read [http://www.shorewall.net/traffic_shaping.htm Shorewall's Traffic Shaping/Control] guide.<br />
<br />
Here is my config as an example:<br />
* /etc/shorewall/tcdevices : here is where you define the interface you want to have shaped and its rates. I have got a ADSL connection with a 4MBit down/256KBit up profile.<br />
ppp0 4mbit 256kbit <br />
* /etc/shorewall/tcclasses : here you define the minimum (rate) and maximum (ceil) throughput per class. You will assign each one to a type of traffic to shape.<br />
# interactive traffic (ssh)<br />
ppp0 1 full full 0<br />
# online gaming<br />
ppp0 2 full/2 full 5<br />
# http<br />
ppp0 3 full/4 full 10<br />
# rest<br />
ppp0 4 full/6 full 15 default<br />
* /etc/shorewall/tcrules : this file contains the types of traffic and the class it belongs to.<br />
1 0.0.0.0/0 0.0.0.0/0 tcp ssh<br />
2 0.0.0.0/0 0.0.0.0/0 udp 27000:28000<br />
3 0.0.0.0/0 0.0.0.0/0 tcp http<br />
3 0.0.0.0/0 0.0.0.0/0 tcp https<br />
I have split it up my traffic in 4 groups: <br />
# interactive traffic or ssh: although it takes up almost no bandwidth, it is very annoying if it lags due to leechers on the LAN. This get the highest priority.<br />
# online gaming: needless to say you ca not play when your ping sucks. ;)<br />
# webtraffic: can be a bit slower<br />
# everything else: every sort of download, they are the cause of the lag anyway.<br />
<br />
===Intrusion detection and prevention with snort===<br />
<br />
See [[Snort]].<br />
<br />
==See also==<br />
*[[Simple stateful firewall]]<br />
*[[Internet sharing]]</div>Branchhttps://wiki.archlinux.org/index.php?title=Router&diff=337059Router2014-09-24T04:45:43Z<p>Branch: /* Acquiring WAN IPv6 via DHCPv6-PD */ dhcpcd.conf - prevent radvd from starting before ia_pd has been acquired</p>
<hr />
<div>[[Category:Networking]]<br />
[[Category:Security]]<br />
This article is a tutorial for turning a computer into an internet gateway/router. It focuses on ''security'', since the gateway is connected directly to the Internet. It should not run '''any''' services available to the outside world. Towards the LAN, it should only run gateway specific services. It should not run httpd, ftpd, samba, nfsd, etc. as those belong on a server in the LAN as they introduce security flaws.<br />
<br />
This article does not attempt to show how to set up a shared connection between 2 PCs using cross-over cables. For a simple internet sharing solution, see [[Internet sharing]].<br />
<br />
==Hardware Requirements==<br />
* At least 1 GB of hard drive space. The base install will take up around 500MB of space and if you want to use a caching web proxy, you will need to reserve space for the cache as well.<br />
* At least two physical network interfaces: a gateway connects two networks with each other. You will need to be able to connect those networks to the same physical computer. One interface must connect to the external network, while the other connects to the internal network.<br />
* A hub, switch or UTP cable: You need a way to connect the other computers to the gateway<br />
<br />
==Conventions==<br />
Conventions in this guide will be to use non-realistic interface names, to avoid confusion about which interface is which.<br />
<br />
* '''intern0''': the network card connected to the LAN. On an actual computer it will probably have the name enp2s0, enp1s1, etc.<br />
* '''extern1''': the network card connected to the external network (or WAN). It will probably have the name enp2s0, enp1s1, etc.<br />
<br />
==Installation==<br />
{{Note | For a full installation guide, see the [[Installation guide]].}}<br />
<br />
A fresh install of Arch Linux is the easiest to start from, as no configuration changes have been made and there is a minimal amount of packages installed. This is helpful when attempting to reduce security risk.<br />
<br />
===Partitioning===<br />
<br />
For security purposes, {{ic|/var}}, {{ic|/tmp}} and {{ic|/home}} should be separate from the {{ic|/}} partition. This prevents disk space from being completely used up by log files, daemons or the unprivileged user. It also allows different mount options for those partitions. If you have already partitioned your drive, the [http://gparted.sourceforge.net/ gparted livecd] can be used to resize, move, or create new partitions.<br />
<br />
Your home and root partitions can be much smaller than a regular install since this is not a desktop machine. {{ic|/var}} should be the largest partition—it is where databases, logs and long-term caches are stored. If you have a lot of RAM, mounting {{ic|/tmp}} as {{ic|tmpfs}} is a good idea, so making a disk partition for it during the initial install is unnecessary. Note that {{ic|/tmp}} is mounted as {{ic|tmpfs}} by default in Arch.<br />
<br />
===Post-Installation===<br />
After creation of non-root account you are recommended to install [[sudo]] and [[sudo#Disable root login|disable root login]].<br />
<br />
==Network interface configuration==<br />
<br />
===Persistent naming and Interface renaming===<br />
Systemd automatically chooses unique interface names for all your interfaces. These are persistent and will not change when you reboot. If you would like to rename interface to user friendlier names read [[Network configuration#Device_names]].<br />
<br />
===IP configuration===<br />
Now you will need to configure the network interfaces. The best way to do so is using [[netctl]] profiles. You will need to create two profiles.<br />
{{Note|If you will be connecting to the Internet only via PPPoE (you have one WAN port) you '''do not need''' to setup or enable the extern0-profile. See below for more information on configuring PPPoE.}}<br />
* {{ic|/etc/netctl/extern0-profile}}<br />
Description='Public Interface.'<br />
Interface=extern0<br />
Connection=ethernet<br />
IP='dhcp'<br />
<br />
* {{ic|/etc/netctl/intern0-profile}}<br />
Description='Private Interface'<br />
Interface=intern0<br />
Connection=ethernet<br />
IP='static'<br />
Address=('10.0.0.1/24')<br />
<br />
{{Note|The example configuration above assumes a full subnet. If you are building the gateway for a small amount of people, you will want to change the CIDR suffix to accommodate a smaller range. For example /27 will give you 10.0.0.1 to 10.0.0.30. You can find many CIDR calculators online.}}<br />
<br />
Next up is to set up the interfaces with netctl.<br />
# netctl enable extern0-profile<br />
# netctl enable intern0-profile<br />
<br />
==ADSL connection/PPPoE==<br />
Using rp-pppoe, we can connect an ADSL modem to the extern1 of the firewall and have Arch manage the connection. Make sure you put the modem in ''bridged'' mode though (either half-bridge or RFC1483), otherwise the modem will act as a router too.<br />
# pacman -S rp-pppoe<br />
<br />
It should be noted that if you use only PPPoE to connect to the internet (ie. you do not have other WAN port, except for the one that connects to your modem) you do not need to set up the {{ic|extern0-profile}} as the external pseudo-interface will be ppp0.<br />
<br />
===PPPoE configuration===<br />
You can use netctl to setup the pppoe connection. To get started<br />
# cp /etc/netctl/examples/pppoe /etc/netctl/<br />
and start editing. For the interface configuration choose the interface that connects to the modem. If you only connect to the internet through PPPoE this will probably be {{ic|extern0}}. Fill in the rest of the fields with your ISP information. See the pppoe section in netctl.profile man page for more information on the fields.<br />
<br />
==DNS and DHCP==<br />
We will use [[dnsmasq]], a DNS and DHCP daemon for the LAN. It was specifically designed for small sites. To get it, [[Pacman | install]] {{Pkg|dnsmasq}} from the [[official repositories]].<br />
<br />
Dnsmasq needs to be configured to be a DHCP server. To do this:<br />
<br />
Edit {{ic|/etc/dnsmasq.conf}}:<br />
<br />
interface=intern0 # make dnsmasq listen for requests only on intern0 (our LAN)<br />
expand-hosts # add a domain to simple hostnames in /etc/hosts<br />
domain=foo.bar # allow fully qualified domain names for DHCP hosts (needed when<br />
# "expand-hosts" is used)<br />
dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # defines a DHCP-range for the LAN: <br />
# from 10.0.0.2 to .255 with a subnet mask of 255.255.255.0 and a<br />
# DHCP lease of 1 hour (change to your own preferences)<br />
<br />
Somewhere below, you will notice you can also add "static" DHCP leases, i.e. assign an IP-address to the MAC-address of a computer on the LAN. This way, whenever the computer requests a new lease, it will get the same IP. That is very useful for network servers with a DNS record. You can also deny certain MAC's from obtaining an IP.<br />
<br />
Now start dnsmasq:<br />
# systemctl start dnsmasq.service<br />
<br />
==Connection sharing==<br />
<br />
Time to tie the two network interfaces to each other.<br />
===iptables===<br />
[[Simple stateful firewall]] documents the setup of an [[iptables]] firewall and NAT.<br />
<br />
Make sure you added the firewall exceptions for DHCP and Domain, if you want to use Dnsmasq:<br />
<br />
* Insert Rules:<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 53 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 53 -j ACCEPT<br />
<br />
<br />
===Shorewall===<br />
Shorewall, an iptables frontend, can be used as an easier alternative. See [[Shorewall]] for detailed configuration.<br />
<br />
==IPv6==<br />
<br />
{{Merge|IPv6|Merge into the main article, the topic is not specific to ''router configuration''. The wording should be probably changed along the way.}}<br />
<br />
''Useful reading: [[IPv6]] and the [https://en.wikipedia.org/wiki/IPv6 Wikipedia IPv6 entry].''<br />
<br />
You can use your router in IPv6 mode even if you do not have an IPv6 address from your ISP. Unless you disable IPv6 all interfaces should have been assigned a unique {{ic|fe80::/10}} address.<br />
<br />
For internal networking the block {{ic|fc00::/7}} has been reserved. These addresses are guaranteed to be unique and non-routable from the open internet. Addresses that belong to the {{ic|fc00::/7}} block are called [http://en.wikipedia.org/wiki/Unique_local_address Unique Local Addresses]. To get started [http://www.simpledns.com/private-ipv6.aspx generate a ULA /64 block] to use in your network. For this example we will use {{ic|fd00:aaaa:bbbb:cccc::/64}}. Firstly we must assign a static IPv6 on the internal interface. Modify the {{ic|intern0-profile}} we created above to include the following line<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::1/64 dev intern0')<br />
This will add the ULA to the internal interface. As far as the router goes, this is all you need to configure.<br />
<br />
===Router Advertisement and Stateless Autoconfiguration (SLAAC)===<br />
<br />
To properly hand out IPv6s to the network clients we will need to use an advertising daemon. The standard tool for this job is {{Pkg|radvd}} and is available in [[official repositories]]. Configuration of radvd is fairly simple. Edit {{ic|/etc/radvd.conf}} to include<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
The above configuration will tell clients to autoconfigure themselves using addresses from the specified /64 block. Addresses on the clients are uniquely generated using the MAC address of the connected interface and are optionally mangled for security reasons if [[IPv6#Privacy_Extensions|privacy extensions]] are enabled (which is recommended to do). On the client side you need to enable {{ic|1=IP6=stateless}} in your active netctl profile. If you want a static IP as well add<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::2/64 dev eth0')<br />
<br />
Don't forget to enable radvd.service<br />
<br />
====Firewall tweaks====<br />
<br />
Stateless autoconfiguration works on the condition that IPv6 icmp packets are allowed throughout the network. So some firewall tweaks are required on both ends of the network for it to work properly. On the '''client side''' all you need to do is allow the {{ic|ipv6-icmp}} protocol on the INPUT chain. If you are using [[Simple stateful firewall]] you only need to add<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
<br />
You can limit it to internal network using {{ic|-s fd00:aaaa:bbbb:cccc::/64}} and/or {{ic|-s fe80::/10}} if you feel it is a security threat. Additionally you must add the same rules to your router firewall but extending it to the OUTPUT and FORWARD chains as well.<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
-A OUTPUT -p ipv6-icmp -j ACCEPT<br />
-A FORWARD -p ipv6-icmp -j ACCEPT<br />
<br />
Again, you can limit it to the internal network for the INPUT chain.<br />
<br />
{{Expansion|More information on IPv6 firewalls required}}<br />
{{Expansion|Additional info on running DHCPv6 server instead of SLAAC}}<br />
<br />
===Global Unicast Addresses===<br />
<br />
====Static WAN IPv6====<br />
<br />
If your ISP or WAN network can access the IPv6 Internet you can assign global link addresses to your router and propagate them through SLAAC to your internal network. If you can use a Static IPv6 all you must do is add it to your external profile and enable it the advertisement of the global unicast block in {{ic|radvd.conf}}.<br />
<br />
In {{ic|/etc/netctl/extern0-profile}} simply add the IPv6 and the IPv6 prefix (usually /64) you have been provided<br />
<br />
IPCustom=('-6 addr add 2002:1:2:3:4:5:6:7/64 dev extern0')<br />
<br />
and edit {{ic|/etc/radvd.conf}} to include the new advertisement block.<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
prefix 2002:1:2:3::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
In that way your internal network clients will also get a Global IPv6 address. This IP is routable from the open internet, so adjust your firewalls. Please note that global and local IPv6s can co-exist on the same interface without further configuration.<br />
<br />
====Acquiring WAN IPv6 via DHCPv6-PD====<br />
<br />
If your ISP handles out IPv6s using [[wikipedia:Prefix_delegation|DHCPv6-PD]] you will need to use a DHCPv6 client to get the IP from your ISP. Common such programs are {{AUR|dibbler}}, {{AUR|wide-dhcpv6}} and {{Pkg|dhcpcd}}. ISC's {{Pkg|dhclient}} should also work, but documentation on prefix delegation is scarce.<br />
<br />
For '''dibbler''' edit {{ic|/etc/dibbler/client.conf}}<br />
<br />
log-mode short<br />
log-level 7<br />
iface "extern0" {<br />
ia<br />
pd<br />
}<br />
<br />
{{Tip|Read manpage '''{{ic|dibbler-client(8)}}''' for more information.}}<br />
<br />
For '''wide-dhcpv6''' edit {{ic|/etc/wide-dhcpv6/dhcp6c.conf}}<br />
<br />
interface extern0 {<br />
send ia-pd 0;<br />
};<br />
<br />
id-assoc pd 0 {<br />
prefix-interface intern0 {<br />
sla-id 1;<br />
sla-len 8;<br />
};<br />
};<br />
<br />
{{Note|1={{ic|sla-len}} should be set so that {{ic|1=(WAN-prefix) + (sla-len) = 64}}. In this case it is set up for a {{ic|/56}} prefix 56+8=64. For a {{ic|/64}} prefix {{ic|sla-len}} should be {{ic|0}}.}}<br />
<br />
To enable/start wide-dhcpv6 client use the command<br />
# systemctl enable/start dhcp6c@extern0.service<br />
<br />
{{Tip|Read manpages '''{{ic|dhcp6c(8)}}''' and '''{{ic|dhcp6c.conf(5)}}''' for more information.}}<br />
<br />
For '''dhcpcd''' edit {{ic|/etc/dhcpcd.conf}}. You might already be using dhcpcd for IPv4 so just update your existing configuration. If you would like to use it for IPv6 only uncomment the third line.<br />
<br />
duid<br />
noipv6rs<br />
waitip 6<br />
#ipv6only<br />
interface extern0<br />
ia_pd 1/::/64 intern0/0/64<br />
<br />
This configuration will ask for a prefix from WAN (interface {{ic|extern0}}) and delegate it to the internal interface ({{ic|intern0}}).<br />
<br />
Because this configuration will neither solicit nor accept router advertisements no default route will be set. The kernel IPv6 stack can be allowed to set a dynamic default route with:<br />
<br />
sysctl -w net.ipv6.conf.extern0.accept_ra=2<br />
<br />
Or to have it persist after reboot:<br />
<br />
echo net.ipv6.conf.extern0.accept_ra = 2 > /etc/sysctl.d/80-ipv6dynroute.conf<br />
<br />
{{Tip|Also read: manpages '''{{ic|dhcpcd(8)}}''' and '''{{ic|dhcpcd.conf(5)}}'''.}}<br />
<br />
Because the IPv6 prefix is now dynamic, we need to change radvd to advertize any subnet instead of specific ones. With this configuration radvd will pick any /64 prefix available on the internal interface and propagate SLAAC IPv6s to the clients. Simply change {{ic|/etc/radvd.conf}} to<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix ::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
DeprecatePrefix on;<br />
};<br />
};<br />
<br />
====PPPoE and IPv6====<br />
If your ISP provides IPv6 via PPPoE you can enable it in your pppoe netctl profile. Just add this to pppoe netctl profile<br />
<br />
PPPoEIP6=yes<br />
<br />
and restart it. Also you must change any {{ic|extern0}} references to the configuration files above to {{ic|ppp0}} instead since IPv6 is assigned to ppp pseudo-interface instead of a real ethernet interface. Please note, that depending on your modem IPv6 might not be available through half-bridge so switch to full RFC1483 bridging instead.<br />
<br />
{{Warning|dhclient does not support DHCP6-PD via PPP}}<br />
<br />
==Cleanup==<br />
<br />
Now that the installation has been performed, it is necessary to remove as many packages as possible. Since we are making a gateway, keeping unneeded packages only "bloats" the system, and increases the number of security risks.<br />
<br />
First, check for obsolete/deprecated packages (likely after a fresh install and massive series of updates):<br />
<br />
$ pacman -Qm<br />
<br />
Review the list of explicitly installed packages that are not dependencies and remove any that are unneeded. Having only needed packages installed is an important security consideration.<br />
<br />
$ pacman -Qet<br />
<br />
Completely remove the packages you do not need along with their configuration files and dependencies:<br />
<br />
# pacman -Rsn package1 package2 package3<br />
<br />
== Logrotate ==<br />
<br />
You should review the [[logrotate]] configuration to make sure the box is not brought down by lack of diskspace due to logging.<br />
<br />
Logrotate is installed by default, so you will not have to install it.<br />
<br />
==Optional additions==<br />
<br />
===UPnP===<br />
The above configuration of shorewall does not include [[Wikipedia:UPnP|UPnP]] support. Use of UPnP is discouraged as it may make the gateway vulnerable to attacks from within the LAN. However, some applications require this to function correctly.<br />
<br />
To enable UPnP on your router, you need to install an UPnP Internet gateway daemon (IGD). To get it, install {{Pkg|miniupnpd}} from the [[official repositories]].<br />
<br />
Read the [http://www.shorewall.net/UPnP.html Shorewall guide on UPnP] for more information<br />
<br />
===Remote administration===<br />
<br />
[[SSH|OpenSSH]] can be used to administer your router remotely. This is useful for running it "headless" (no monitor or input devices).<br />
<br />
=== Caching web proxy ===<br />
<br />
See [[Squid]] or [[Polipo]] for the setup of a web proxy to speed up browsing and/or adding an extra layer of security.<br />
<br />
=== Time server ===<br />
To use the router as a time server, see [[Network Time Protocol daemon]].<br />
<br />
Then, configure shorewall or iptables to allow NTP traffic in and out.<br />
<br />
=== Content filtering ===<br />
<br />
Install and configure [[DansGuardian]] or [[Privoxy]] if you need a content filtering solution.<br />
<br />
=== Traffic shaping ===<br />
<br />
Traffic shaping is very useful, especially when you are not the only one on the LAN. The idea is to assign a priority to different types of traffic. Interactive traffic (ssh, online gaming) probably needs the highest priority, while P2P traffic can do with the lowest. Then there is everything in between.<br />
<br />
==== Traffic shaping with shorewall ====<br />
<br />
Read [http://www.shorewall.net/traffic_shaping.htm Shorewall's Traffic Shaping/Control] guide.<br />
<br />
Here is my config as an example:<br />
* /etc/shorewall/tcdevices : here is where you define the interface you want to have shaped and its rates. I have got a ADSL connection with a 4MBit down/256KBit up profile.<br />
ppp0 4mbit 256kbit <br />
* /etc/shorewall/tcclasses : here you define the minimum (rate) and maximum (ceil) throughput per class. You will assign each one to a type of traffic to shape.<br />
# interactive traffic (ssh)<br />
ppp0 1 full full 0<br />
# online gaming<br />
ppp0 2 full/2 full 5<br />
# http<br />
ppp0 3 full/4 full 10<br />
# rest<br />
ppp0 4 full/6 full 15 default<br />
* /etc/shorewall/tcrules : this file contains the types of traffic and the class it belongs to.<br />
1 0.0.0.0/0 0.0.0.0/0 tcp ssh<br />
2 0.0.0.0/0 0.0.0.0/0 udp 27000:28000<br />
3 0.0.0.0/0 0.0.0.0/0 tcp http<br />
3 0.0.0.0/0 0.0.0.0/0 tcp https<br />
I have split it up my traffic in 4 groups: <br />
# interactive traffic or ssh: although it takes up almost no bandwidth, it is very annoying if it lags due to leechers on the LAN. This get the highest priority.<br />
# online gaming: needless to say you ca not play when your ping sucks. ;)<br />
# webtraffic: can be a bit slower<br />
# everything else: every sort of download, they are the cause of the lag anyway.<br />
<br />
===Intrusion detection and prevention with snort===<br />
<br />
See [[Snort]].<br />
<br />
==See also==<br />
*[[Simple stateful firewall]]<br />
*[[Internet sharing]]</div>Branchhttps://wiki.archlinux.org/index.php?title=Router&diff=336854Router2014-09-22T22:41:21Z<p>Branch: /* Acquiring WAN IPv6 via DHCPv6-PD */ Fix dhcpcd.conf ia_pd line for newer versions of dhcpcd.</p>
<hr />
<div>[[Category:Networking]]<br />
[[Category:Security]]<br />
This article is a tutorial for turning a computer into an internet gateway/router. It focuses on ''security'', since the gateway is connected directly to the Internet. It should not run '''any''' services available to the outside world. Towards the LAN, it should only run gateway specific services. It should not run httpd, ftpd, samba, nfsd, etc. as those belong on a server in the LAN as they introduce security flaws.<br />
<br />
This article does not attempt to show how to set up a shared connection between 2 PCs using cross-over cables. For a simple internet sharing solution, see [[Internet sharing]].<br />
<br />
==Hardware Requirements==<br />
* At least 1 GB of hard drive space. The base install will take up around 500MB of space and if you want to use a caching web proxy, you will need to reserve space for the cache as well.<br />
* At least two physical network interfaces: a gateway connects two networks with each other. You will need to be able to connect those networks to the same physical computer. One interface must connect to the external network, while the other connects to the internal network.<br />
* A hub, switch or UTP cable: You need a way to connect the other computers to the gateway<br />
<br />
==Conventions==<br />
Conventions in this guide will be to use non-realistic interface names, to avoid confusion about which interface is which.<br />
<br />
* '''intern0''': the network card connected to the LAN. On an actual computer it will probably have the name enp2s0, enp1s1, etc.<br />
* '''extern1''': the network card connected to the external network (or WAN). It will probably have the name enp2s0, enp1s1, etc.<br />
<br />
==Installation==<br />
{{Note | For a full installation guide, see the [[Installation guide]].}}<br />
<br />
A fresh install of Arch Linux is the easiest to start from, as no configuration changes have been made and there is a minimal amount of packages installed. This is helpful when attempting to reduce security risk.<br />
<br />
===Partitioning===<br />
<br />
For security purposes, {{ic|/var}}, {{ic|/tmp}} and {{ic|/home}} should be separate from the {{ic|/}} partition. This prevents disk space from being completely used up by log files, daemons or the unprivileged user. It also allows different mount options for those partitions. If you have already partitioned your drive, the [http://gparted.sourceforge.net/ gparted livecd] can be used to resize, move, or create new partitions.<br />
<br />
Your home and root partitions can be much smaller than a regular install since this is not a desktop machine. {{ic|/var}} should be the largest partition—it is where databases, logs and long-term caches are stored. If you have a lot of RAM, mounting {{ic|/tmp}} as {{ic|tmpfs}} is a good idea, so making a disk partition for it during the initial install is unnecessary. Note that {{ic|/tmp}} is mounted as {{ic|tmpfs}} by default in Arch.<br />
<br />
===Post-Installation===<br />
After creation of non-root account you are recommended to install [[sudo]] and [[sudo#Disable root login|disable root login]].<br />
<br />
==Network interface configuration==<br />
<br />
===Persistent naming and Interface renaming===<br />
Systemd automatically chooses unique interface names for all your interfaces. These are persistent and will not change when you reboot. If you would like to rename interface to user friendlier names read [[Network configuration#Device_names]].<br />
<br />
===IP configuration===<br />
Now you will need to configure the network interfaces. The best way to do so is using [[netctl]] profiles. You will need to create two profiles.<br />
{{Note|If you will be connecting to the Internet only via PPPoE (you have one WAN port) you '''do not need''' to setup or enable the extern0-profile. See below for more information on configuring PPPoE.}}<br />
* {{ic|/etc/netctl/extern0-profile}}<br />
Description='Public Interface.'<br />
Interface=extern0<br />
Connection=ethernet<br />
IP='dhcp'<br />
<br />
* {{ic|/etc/netctl/intern0-profile}}<br />
Description='Private Interface'<br />
Interface=intern0<br />
Connection=ethernet<br />
IP='static'<br />
Address=('10.0.0.1/24')<br />
<br />
{{Note|The example configuration above assumes a full subnet. If you are building the gateway for a small amount of people, you will want to change the CIDR suffix to accommodate a smaller range. For example /27 will give you 10.0.0.1 to 10.0.0.30. You can find many CIDR calculators online.}}<br />
<br />
Next up is to set up the interfaces with netctl.<br />
# netctl enable extern0-profile<br />
# netctl enable intern0-profile<br />
<br />
==ADSL connection/PPPoE==<br />
Using rp-pppoe, we can connect an ADSL modem to the extern1 of the firewall and have Arch manage the connection. Make sure you put the modem in ''bridged'' mode though (either half-bridge or RFC1483), otherwise the modem will act as a router too.<br />
# pacman -S rp-pppoe<br />
<br />
It should be noted that if you use only PPPoE to connect to the internet (ie. you do not have other WAN port, except for the one that connects to your modem) you do not need to set up the {{ic|extern0-profile}} as the external pseudo-interface will be ppp0.<br />
<br />
===PPPoE configuration===<br />
You can use netctl to setup the pppoe connection. To get started<br />
# cp /etc/netctl/examples/pppoe /etc/netctl/<br />
and start editing. For the interface configuration choose the interface that connects to the modem. If you only connect to the internet through PPPoE this will probably be {{ic|extern0}}. Fill in the rest of the fields with your ISP information. See the pppoe section in netctl.profile man page for more information on the fields.<br />
<br />
==DNS and DHCP==<br />
We will use [[dnsmasq]], a DNS and DHCP daemon for the LAN. It was specifically designed for small sites. To get it, [[Pacman | install]] {{Pkg|dnsmasq}} from the [[official repositories]].<br />
<br />
Dnsmasq needs to be configured to be a DHCP server. To do this:<br />
<br />
Edit {{ic|/etc/dnsmasq.conf}}:<br />
<br />
interface=intern0 # make dnsmasq listen for requests only on intern0 (our LAN)<br />
expand-hosts # add a domain to simple hostnames in /etc/hosts<br />
domain=foo.bar # allow fully qualified domain names for DHCP hosts (needed when<br />
# "expand-hosts" is used)<br />
dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # defines a DHCP-range for the LAN: <br />
# from 10.0.0.2 to .255 with a subnet mask of 255.255.255.0 and a<br />
# DHCP lease of 1 hour (change to your own preferences)<br />
<br />
Somewhere below, you will notice you can also add "static" DHCP leases, i.e. assign an IP-address to the MAC-address of a computer on the LAN. This way, whenever the computer requests a new lease, it will get the same IP. That is very useful for network servers with a DNS record. You can also deny certain MAC's from obtaining an IP.<br />
<br />
Now start dnsmasq:<br />
# systemctl start dnsmasq.service<br />
<br />
==Connection sharing==<br />
<br />
Time to tie the two network interfaces to each other.<br />
===iptables===<br />
[[Simple stateful firewall]] documents the setup of an [[iptables]] firewall and NAT.<br />
<br />
Make sure you added the firewall exceptions for DHCP and Domain, if you want to use Dnsmasq:<br />
<br />
* Insert Rules:<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 53 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 53 -j ACCEPT<br />
<br />
<br />
===Shorewall===<br />
Shorewall, an iptables frontend, can be used as an easier alternative. See [[Shorewall]] for detailed configuration.<br />
<br />
==IPv6==<br />
<br />
{{Merge|IPv6|Merge into the main article, the topic is not specific to ''router configuration''. The wording should be probably changed along the way.}}<br />
<br />
''Useful reading: [[IPv6]] and the [https://en.wikipedia.org/wiki/IPv6 Wikipedia IPv6 entry].''<br />
<br />
You can use your router in IPv6 mode even if you do not have an IPv6 address from your ISP. Unless you disable IPv6 all interfaces should have been assigned a unique {{ic|fe80::/10}} address.<br />
<br />
For internal networking the block {{ic|fc00::/7}} has been reserved. These addresses are guaranteed to be unique and non-routable from the open internet. Addresses that belong to the {{ic|fc00::/7}} block are called [http://en.wikipedia.org/wiki/Unique_local_address Unique Local Addresses]. To get started [http://www.simpledns.com/private-ipv6.aspx generate a ULA /64 block] to use in your network. For this example we will use {{ic|fd00:aaaa:bbbb:cccc::/64}}. Firstly we must assign a static IPv6 on the internal interface. Modify the {{ic|intern0-profile}} we created above to include the following line<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::1/64 dev intern0')<br />
This will add the ULA to the internal interface. As far as the router goes, this is all you need to configure.<br />
<br />
===Router Advertisement and Stateless Autoconfiguration (SLAAC)===<br />
<br />
To properly hand out IPv6s to the network clients we will need to use an advertising daemon. The standard tool for this job is {{Pkg|radvd}} and is available in [[official repositories]]. Configuration of radvd is fairly simple. Edit {{ic|/etc/radvd.conf}} to include<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
The above configuration will tell clients to autoconfigure themselves using addresses from the specified /64 block. Addresses on the clients are uniquely generated using the MAC address of the connected interface and are optionally mangled for security reasons if [[IPv6#Privacy_Extensions|privacy extensions]] are enabled (which is recommended to do). On the client side you need to enable {{ic|1=IP6=stateless}} in your active netctl profile. If you want a static IP as well add<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::2/64 dev eth0')<br />
<br />
Don't forget to enable radvd.service<br />
<br />
====Firewall tweaks====<br />
<br />
Stateless autoconfiguration works on the condition that IPv6 icmp packets are allowed throughout the network. So some firewall tweaks are required on both ends of the network for it to work properly. On the '''client side''' all you need to do is allow the {{ic|ipv6-icmp}} protocol on the INPUT chain. If you are using [[Simple stateful firewall]] you only need to add<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
<br />
You can limit it to internal network using {{ic|-s fd00:aaaa:bbbb:cccc::/64}} and/or {{ic|-s fe80::/10}} if you feel it is a security threat. Additionally you must add the same rules to your router firewall but extending it to the OUTPUT and FORWARD chains as well.<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
-A OUTPUT -p ipv6-icmp -j ACCEPT<br />
-A FORWARD -p ipv6-icmp -j ACCEPT<br />
<br />
Again, you can limit it to the internal network for the INPUT chain.<br />
<br />
{{Expansion|More information on IPv6 firewalls required}}<br />
{{Expansion|Additional info on running DHCPv6 server instead of SLAAC}}<br />
<br />
===Global Unicast Addresses===<br />
<br />
====Static WAN IPv6====<br />
<br />
If your ISP or WAN network can access the IPv6 Internet you can assign global link addresses to your router and propagate them through SLAAC to your internal network. If you can use a Static IPv6 all you must do is add it to your external profile and enable it the advertisement of the global unicast block in {{ic|radvd.conf}}.<br />
<br />
In {{ic|/etc/netctl/extern0-profile}} simply add the IPv6 and the IPv6 prefix (usually /64) you have been provided<br />
<br />
IPCustom=('-6 addr add 2002:1:2:3:4:5:6:7/64 dev extern0')<br />
<br />
and edit {{ic|/etc/radvd.conf}} to include the new advertisement block.<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
prefix 2002:1:2:3::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
In that way your internal network clients will also get a Global IPv6 address. This IP is routable from the open internet, so adjust your firewalls. Please note that global and local IPv6s can co-exist on the same interface without further configuration.<br />
<br />
====Acquiring WAN IPv6 via DHCPv6-PD====<br />
<br />
If your ISP handles out IPv6s using [[wikipedia:Prefix_delegation|DHCPv6-PD]] you will need to use a DHCPv6 client to get the IP from your ISP. Common such programs are {{AUR|dibbler}}, {{AUR|wide-dhcpv6}} and {{Pkg|dhcpcd}}. ISC's {{Pkg|dhclient}} should also work, but documentation on prefix delegation is scarce.<br />
<br />
For '''dibbler''' edit {{ic|/etc/dibbler/client.conf}}<br />
<br />
log-mode short<br />
log-level 7<br />
iface "extern0" {<br />
ia<br />
pd<br />
}<br />
<br />
{{Tip|Read manpage '''{{ic|dibbler-client(8)}}''' for more information.}}<br />
<br />
For '''wide-dhcpv6''' edit {{ic|/etc/wide-dhcpv6/dhcp6c.conf}}<br />
<br />
interface extern0 {<br />
send ia-pd 0;<br />
};<br />
<br />
id-assoc pd 0 {<br />
prefix-interface intern0 {<br />
sla-id 1;<br />
sla-len 8;<br />
};<br />
};<br />
<br />
{{Note|1={{ic|sla-len}} should be set so that {{ic|1=(WAN-prefix) + (sla-len) = 64}}. In this case it is set up for a {{ic|/56}} prefix 56+8=64. For a {{ic|/64}} prefix {{ic|sla-len}} should be {{ic|0}}.}}<br />
<br />
To enable/start wide-dhcpv6 client use the command<br />
# systemctl enable/start dhcp6c@extern0.service<br />
<br />
{{Tip|Read manpages '''{{ic|dhcp6c(8)}}''' and '''{{ic|dhcp6c.conf(5)}}''' for more information.}}<br />
<br />
For '''dhcpcd''' edit {{ic|/etc/dhcpcd.conf}}. You might already be using dhcpcd for IPv4 so just update your existing configuration. If you would like to use it for IPv6 only uncomment the third line.<br />
<br />
duid<br />
noipv6rs<br />
#ipv6only<br />
interface extern0<br />
ia_pd 1/::/64 intern0/0/64<br />
<br />
This configuration will ask for a prefix from WAN (interface {{ic|extern0}}) and delegate it to the internal interface ({{ic|intern0}}).<br />
<br />
Because this configuration will neither solicit nor accept router advertisements no default route will be set. The kernel IPv6 stack can be allowed to set a dynamic default route with:<br />
<br />
sysctl -w net.ipv6.conf.extern0.accept_ra=2<br />
<br />
Or to have it persist after reboot:<br />
<br />
echo net.ipv6.conf.extern0.accept_ra = 2 > /etc/sysctl.d/80-ipv6dynroute.conf<br />
<br />
{{Tip|Also read: manpages '''{{ic|dhcpcd(8)}}''' and '''{{ic|dhcpcd.conf(5)}}'''.}}<br />
<br />
Because the IPv6 prefix is now dynamic, we need to change radvd to advertize any subnet instead of specific ones. With this configuration radvd will pick any /64 prefix available on the internal interface and propagate SLAAC IPv6s to the clients. Simply change {{ic|/etc/radvd.conf}} to<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix ::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
DeprecatePrefix on;<br />
};<br />
};<br />
<br />
====PPPoE and IPv6====<br />
If your ISP provides IPv6 via PPPoE you can enable it in your pppoe netctl profile. Just add this to pppoe netctl profile<br />
<br />
PPPoEIP6=yes<br />
<br />
and restart it. Also you must change any {{ic|extern0}} references to the configuration files above to {{ic|ppp0}} instead since IPv6 is assigned to ppp pseudo-interface instead of a real ethernet interface. Please note, that depending on your modem IPv6 might not be available through half-bridge so switch to full RFC1483 bridging instead.<br />
<br />
{{Warning|dhclient does not support DHCP6-PD via PPP}}<br />
<br />
==Cleanup==<br />
<br />
Now that the installation has been performed, it is necessary to remove as many packages as possible. Since we are making a gateway, keeping unneeded packages only "bloats" the system, and increases the number of security risks.<br />
<br />
First, check for obsolete/deprecated packages (likely after a fresh install and massive series of updates):<br />
<br />
$ pacman -Qm<br />
<br />
Review the list of explicitly installed packages that are not dependencies and remove any that are unneeded. Having only needed packages installed is an important security consideration.<br />
<br />
$ pacman -Qet<br />
<br />
Completely remove the packages you do not need along with their configuration files and dependencies:<br />
<br />
# pacman -Rsn package1 package2 package3<br />
<br />
== Logrotate ==<br />
<br />
You should review the [[logrotate]] configuration to make sure the box is not brought down by lack of diskspace due to logging.<br />
<br />
Logrotate is installed by default, so you will not have to install it.<br />
<br />
==Optional additions==<br />
<br />
===UPnP===<br />
The above configuration of shorewall does not include [[Wikipedia:UPnP|UPnP]] support. Use of UPnP is discouraged as it may make the gateway vulnerable to attacks from within the LAN. However, some applications require this to function correctly.<br />
<br />
To enable UPnP on your router, you need to install an UPnP Internet gateway daemon (IGD). To get it, install {{Pkg|miniupnpd}} from the [[official repositories]].<br />
<br />
Read the [http://www.shorewall.net/UPnP.html Shorewall guide on UPnP] for more information<br />
<br />
===Remote administration===<br />
<br />
[[SSH|OpenSSH]] can be used to administer your router remotely. This is useful for running it "headless" (no monitor or input devices).<br />
<br />
=== Caching web proxy ===<br />
<br />
See [[Squid]] or [[Polipo]] for the setup of a web proxy to speed up browsing and/or adding an extra layer of security.<br />
<br />
=== Time server ===<br />
To use the router as a time server, see [[Network Time Protocol daemon]].<br />
<br />
Then, configure shorewall or iptables to allow NTP traffic in and out.<br />
<br />
=== Content filtering ===<br />
<br />
Install and configure [[DansGuardian]] or [[Privoxy]] if you need a content filtering solution.<br />
<br />
=== Traffic shaping ===<br />
<br />
Traffic shaping is very useful, especially when you are not the only one on the LAN. The idea is to assign a priority to different types of traffic. Interactive traffic (ssh, online gaming) probably needs the highest priority, while P2P traffic can do with the lowest. Then there is everything in between.<br />
<br />
==== Traffic shaping with shorewall ====<br />
<br />
Read [http://www.shorewall.net/traffic_shaping.htm Shorewall's Traffic Shaping/Control] guide.<br />
<br />
Here is my config as an example:<br />
* /etc/shorewall/tcdevices : here is where you define the interface you want to have shaped and its rates. I have got a ADSL connection with a 4MBit down/256KBit up profile.<br />
ppp0 4mbit 256kbit <br />
* /etc/shorewall/tcclasses : here you define the minimum (rate) and maximum (ceil) throughput per class. You will assign each one to a type of traffic to shape.<br />
# interactive traffic (ssh)<br />
ppp0 1 full full 0<br />
# online gaming<br />
ppp0 2 full/2 full 5<br />
# http<br />
ppp0 3 full/4 full 10<br />
# rest<br />
ppp0 4 full/6 full 15 default<br />
* /etc/shorewall/tcrules : this file contains the types of traffic and the class it belongs to.<br />
1 0.0.0.0/0 0.0.0.0/0 tcp ssh<br />
2 0.0.0.0/0 0.0.0.0/0 udp 27000:28000<br />
3 0.0.0.0/0 0.0.0.0/0 tcp http<br />
3 0.0.0.0/0 0.0.0.0/0 tcp https<br />
I have split it up my traffic in 4 groups: <br />
# interactive traffic or ssh: although it takes up almost no bandwidth, it is very annoying if it lags due to leechers on the LAN. This get the highest priority.<br />
# online gaming: needless to say you ca not play when your ping sucks. ;)<br />
# webtraffic: can be a bit slower<br />
# everything else: every sort of download, they are the cause of the lag anyway.<br />
<br />
===Intrusion detection and prevention with snort===<br />
<br />
See [[Snort]].<br />
<br />
==See also==<br />
*[[Simple stateful firewall]]<br />
*[[Internet sharing]]</div>Branchhttps://wiki.archlinux.org/index.php?title=Convert_FLAC_to_MP3&diff=309094Convert FLAC to MP32014-04-07T05:38:36Z<p>Branch: /* Scripts */ Added Makefile for recursively transcoding flac to mp3 with ffmpeg</p>
<hr />
<div>[[Category:Audio/Video]]<br />
[[Category:Scripts]]<br />
{{Related articles start}}<br />
{{Related|Convert Any To Mp3}}<br />
{{Related|Convert any Movie to DVD Video}}<br />
{{Related articles end}}<br />
<br />
This article presents ways of doing audio transcoding between FLAC and MP3 audio files using command line/scripted tools, and suggest a few graphical utilities to do the same and more.<br />
<br />
== Scripts ==<br />
<br />
In these two examples, FLAC files in current directory are read and streamed into the LAME MP3 encoder. Both scripts pass the ID3 tags from the FLAC files to the resulting MP3 files, and encode to MP3 V0. V0 is equivalent to {{ic|--preset extreme}} which results in a variable bitrate usually between 220-260 kbps. The audio of a V0 file is transparent, meaning one cannot tell the difference between the lossy file and the original source (compact disc/lossless), but yet the file size is a quite lower. For more information on LAME switches/settings such as V0, visit the [http://wiki.hydrogenaudio.org/index.php?title=LAME Hydrogenaudio LAME Wiki]. <br />
<br />
The original {{ic|.flac}} files are not modified and the resulting {{ic|.mp3}}s will be in the same directory. All files with extensions not matching {{ic|*.flac}} in the working directory ({{ic|.nfo}}, images, {{ic|.sfv}}, etc.) are ignored.<br />
<br />
=== With FFmpeg ===<br />
<br />
Chances are, your system already has {{Pkg|ffmpeg}} installed, which brings in the {{Pkg|flac}} and {{Pkg|lame}} packages. FFmpeg has all the encoding and decoding facilities built in to do the job.<br />
<br />
{{bc|<br />
#!/bin/bash<br />
<br />
for a in *.flac; do<br />
< /dev/null ffmpeg -i "$a" -qscale:a 0 "${a[@]/%flac/mp3}"<br />
done<br />
}}<br />
<br />
==== Parallel version ====<br />
<br />
Conversion can be accelerated if you have multicore CPU/several CPUs:<br />
<br />
{{bc|<nowiki><br />
parallel -j 4 'a={}; ffmpeg -i "$a" -qscale:a 0 "${a[@]/%flac/mp3}"' ::: *.flac<br />
</nowiki>}}<br />
<br />
==== Makefile for incremental recursive transcoding ====<br />
<br />
Besides transcoding in parallel with 'make -j$(nproc)', this has the added benefit of not regenerating transcoded files that already exist on subsequent executions:<br />
<br />
{{bc|<nowiki><br />
SOURCE_DIR := flacdir<br />
XCODE_MP3_DIR := mp3dir<br />
# NOTE: see lame -v option for quality meaning<br />
XCODE_MP3_QUALITY := 0<br />
<br />
# Find .flac sources and determine corresponding targets<br />
flac_srcs := $(shell find $(SOURCE_DIR) -type f -name '*.flac')<br />
flac_2_mp3_tgts := $(patsubst $(SOURCE_DIR)/%.flac, $(XCODE_MP3_DIR)/%.mp3, \<br />
$(flac_srcs))<br />
<br />
.PHONY: all mp3 flac_2_mp3<br />
<br />
all: mp3 <br />
<br />
mp3: flac_2_mp3<br />
<br />
flac_2_mp3: $(flac_2_mp3_tgts)<br />
<br />
$(XCODE_MP3_DIR)/%.mp3: $(SOURCE_DIR)/%.flac<br />
@echo "converting -> $@"<br />
@mkdir -p "$(@D)"<br />
@ffmpeg -v error -i "$<" -codec:a libmp3lame \<br />
-q:a $(XCODE_MP3_QUALITY) "$(@)"<br />
</nowiki>}}<br />
<br />
=== Without FFmpeg ===<br />
<br />
If for some reason FFmpeg isn't installed and you don't want to install it, you still need to have {{Pkg|flac}} and {{Pkg|lame}} installed. Here, the tagging process is more explicit using the metadata utility that comes with {{Pkg|flac}} and passing the information to {{Pkg|lame}}. The process duration will slightly increase since FLACs must first be decoded to WAVE and then fed into the MP3 encoder.<br />
<br />
{{bc|<nowiki><br />
#!/bin/bash<br />
<br />
for a in *.flac; do<br />
# give output correct extension<br />
OUTF="${a[@]/%flac/mp3}"<br />
<br />
# get the tags<br />
ARTIST=$(metaflac "$a" --show-tag=ARTIST | sed s/.*=//g)<br />
TITLE=$(metaflac "$a" --show-tag=TITLE | sed s/.*=//g)<br />
ALBUM=$(metaflac "$a" --show-tag=ALBUM | sed s/.*=//g)<br />
GENRE=$(metaflac "$a" --show-tag=GENRE | sed s/.*=//g)<br />
TRACKNUMBER=$(metaflac "$a" --show-tag=TRACKNUMBER | sed s/.*=//g)<br />
DATE=$(metaflac "$a" --show-tag=DATE | sed s/.*=//g)<br />
<br />
# stream flac into the lame encoder<br />
flac -c -d "$a" | lame -V0 --add-id3v2 --pad-id3v2 --ignore-tag-errors \<br />
--ta "$ARTIST" --tt "$TITLE" --tl "$ALBUM" --tg "${GENRE:-12}" \<br />
--tn "${TRACKNUMBER:-0}" --ty "$DATE" - "$OUTF"<br />
done<br />
</nowiki>}}<br />
<br />
=== Recursively ===<br />
A useful extension of the above scripts is to let them recurse into all subdirectories of the working directory. To do so, replace the first line ({{ic|for .... do}}) with:<br />
<br />
find -type f -name "*.flac" -print0 | while read -d $'\0' a; do<br />
<br />
=== Usage ===<br />
<br />
For ease of use, add the script to your {{ic|PATH}}. Open up a terminal, {{ic|cd}} to the directory of FLAC files that you wish to convert, and invoke {{ic|flac2mp3}} (or whatever you named the script). You'll see the verbose decoding/encoding process in the terminal which may take a few moments. Done! At this point, it's trivial to {{ic|mv *.mp3}} all your new MP3s wherever you wish.<br />
<br />
=== Packages ===<br />
<br />
* {{AUR|whatmp3}} - A small Python script that accepts a list of directories containing FLAC files as arguments and converts them to MP3 with the specified options.<br />
* {{AUR|flac2all}} - Audio converter of FLAC to either Ogg Vorbis or MP3 retaining all tags and metadata.<br />
* {{AUR|flac2mp3-bash}} - Bash script to convert Flac to Mp3 easily.<br />
<br />
== Graphical applications ==<br />
<br />
{{Merge|List of applications|This page is categorized under [[:Category:Scripts]], graphical programs should not be here.}}<br />
<br />
*{{App|SoundConverter|A dedicated audio transcoding utility built for the [[GNOME]] desktop and relying on GStreamer. It can make use of [http://library.gnome.org/users/gnome-audio-profiles/stable/gnome-audio-profiles-usage.html.en GNOME Audio Profiles] and features multithreaded conversions. It can also extract the audio from videos.|http://soundconverter.org/|{{Pkg|soundconverter}}}}<br />
*{{App|soundKonverter|A Qt graphical frontend to various audio manipulation programs. Features conversion, ripping and other audio manipulation functionalities.|https://github.com/HessiJames/soundkonverter/wiki|{{Pkg|soundkonverter}}}}<br />
*{{App|[[Wikipedia:FFmpeg#Projects_using_FFmpeg|WinFF]]|A GUI for the powerful multimedia converter FFmpeg. Features dedicated profiles for audio transcoding.|http://code.google.com/p/winff/|{{Pkg|winff}}}}<br />
<br />
== See also ==<br />
<br />
* https://www.xiph.org/flac/<br />
* https://en.wikipedia.org/wiki/FLAC<br />
* http://lame.sourceforge.net/<br />
* http://wiki.hydrogenaudio.org/index.php?title=Flac - More information on FLAC.</div>Branchhttps://wiki.archlinux.org/index.php?title=Simple_stateful_firewall&diff=307801Simple stateful firewall2014-03-31T15:52:59Z<p>Branch: /* IPv6 */</p>
<hr />
<div>[[Category:Firewalls]]<br />
[[ru:Simple stateful firewall]]<br />
This page explains how to set up a stateful firewall using [[iptables]]. It also explains what the rules mean and why they are needed. For simplicity, it is split into two major sections. The first section deals with a firewall for a single machine, the second sets up a NAT gateway in addition to the firewall from the first section.<br />
<br />
{{Warning| The rules are given in the order that they are executed. If you are logged into a remote machine, you may be locked out of the machine while setting up the rules. You should only follow the steps below while you are logged in locally.<br />
<br />
The [https://wiki.archlinux.org/index.php/Simple_Stateful_Firewall#Example_iptables.rules_file example config file] can be used to get around this problem.<br />
}}<br />
<br />
== Prerequisites ==<br />
<br />
{{Note|Your kernel needs to be compiled with iptables support. All stock Arch Linux kernels have iptables support.}}<br />
<br />
First, install the userland utilities {{Pkg|iptables}} or verify that they are already installed.<br />
<br />
This article assumes that there are currently no iptables rules set. To check the current ruleset and verify that there are currently no rules run the following:<br />
<br />
{{hc|# iptables-save|<nowiki><br />
# Generated by iptables-save v1.4.19.1 on Thu Aug 1 19:28:53 2013<br />
*filter<br />
:INPUT ACCEPT [50:3763]<br />
:FORWARD ACCEPT [0:0]<br />
:OUTPUT ACCEPT [30:3472]<br />
COMMIT<br />
# Completed on Thu Aug 1 19:28:53 2013<br />
</nowiki>}}<br />
<br />
or<br />
<br />
{{hc|# iptables -nvL --line-numbers|<nowiki><br />
Chain INPUT (policy ACCEPT 156 packets, 12541 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain OUTPUT (policy ACCEPT 82 packets, 8672 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
</nowiki>}}<br />
<br />
If there are rules, you may be able to reset the rules by loading a default rule set:<br />
<br />
# iptables-restore < /etc/iptables/empty.rules<br />
<br />
Otherwise, see [[Iptables#Resetting_rules]].<br />
<br />
== Firewall for a single machine ==<br />
<br />
{{Note|Because iptables processes rules in linear order, from top to bottom within a chain, it is advised to put frequently-hit rules near the start of the chain. Of course there is a limit, depending on the logic that is being implemented. Also, rules have an associated runtime cost, so rules should not be reordered solely based upon empirical observations of the byte/packet counters.}}<br />
<br />
=== Creating necessary chains ===<br />
<br />
For this basic setup, we will create two user-defined chains that we will use to open up ports in the firewall.<br />
<br />
# iptables -N TCP<br />
# iptables -N UDP<br />
<br />
The chains can of course have arbitrary names. We pick these just to match the protocols we want handle with them in the later rules, which are specified with the protocol options, e.g. {{ic|-p tcp}}, always.<br />
<br />
=== The FORWARD chain ===<br />
<br />
If you want to set up your machine as a NAT gateway, please look at the [[#Setting up a NAT gateway|second section of this guide]]. For a single machine, however, we simply set the policy of the '''FORWARD''' chain to '''DROP''' and move on:<br />
<br />
# iptables -P FORWARD DROP<br />
<br />
=== The OUTPUT chain ===<br />
<br />
We have no intention of filtering any outgoing traffic, as this would make the setup much more complicated and would require some extra thought. In this simple case, we set the '''OUTPUT''' policy to '''ACCEPT'''.<br />
<br />
# iptables -P OUTPUT ACCEPT<br />
<br />
=== The INPUT chain ===<br />
<br />
First, we set the default policy for the '''INPUT''' chain to '''DROP''' in case something somehow slips by our rules. Dropping all traffic and specifying what is allowed is the best way to make a secure firewall.<br />
{{Warning|This is the step where you will be locked out if you are logged in via SSH. Therefore do this step following your rule regarding port 22 (or whatever port you're using for SSH) to prevent being locked out.}}<br />
<br />
# iptables -P INPUT DROP<br />
<br />
Every packet that is received by any network interface will pass the '''INPUT''' chain first, if it is destined for this machine. In this chain, we make sure that only the packets that we want are accepted.<br />
<br />
The first rule will allow traffic that belongs to established connections, or new valid traffic that is related to these connections such as ICMP errors, or echo replies (the packets a host returns when pinged). '''ICMP''' stands for '''Internet Control Message Protocol'''. Some ICMP messages are very important and help to manage congestion and MTU, and are accepted by this rule.<br />
<br />
# iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The second rule will accept all traffic from the "loopback" (lo) interface, which is necessary for many applications and services.<br />
<br />
{{Note|You can add more trusted interfaces here such as "eth1" if you do not want/need the traffic filtered by the firewall, but be warned that if you have a NAT setup that redirects any kind of traffic to this interface from anywhere else in the network (let's say a router), it'll get through, regardless of any other settings you may have.}}<br />
<br />
# iptables -A INPUT -i lo -j ACCEPT<br />
<br />
The third rule will drop all traffic with an "INVALID" state match. Traffic can fall into four "state" categories: NEW, ESTABLISHED, RELATED or INVALID and this is what makes this a "stateful" firewall rather than a less secure "stateless" one. States are tracked using the "nf_conntrack_*" kernel modules which are loaded automatically by the kernel as you add rules.<br />
<br />
{{Note|<br />
* This rule will drop all packets with invalid headers or checksums, invalid TCP flags, invalid ICMP messages (such as a port unreachable when we did not send anything to the host), and out of sequence packets which can be caused by sequence prediction or other similar attacks. The "DROP" target will drop a packet without any response, contrary to REJECT which politely refuses the packet. We use DROP because there is no proper "REJECT" response to packets that are INVALID, and we do not want to acknowledge that we received these packets.<br />
* ICMPv6 Neighbor Discovery packets remain untracked, and will always be classified "INVALID" though they are not corrupted or the like. Keep this in mind, and accept them before this rule! iptables -A INPUT -p 41 -j ACCEPT<br />
}}<br />
<br />
# iptables -A INPUT -m conntrack --ctstate INVALID -j DROP<br />
<br />
The next rule will accept all new incoming '''ICMP echo requests''', also known as pings. Only the first packet will count as NEW, the rest will be handled by the RELATED,ESTABLISHED rule. Since the computer is not a router, no other ICMP traffic with state NEW needs to be allowed.<br />
<br />
# iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Now we attach the TCP and UDP chains to the INPUT chain to handle all new incoming connections. Once a connection is accepted by either TCP or UDP chain, it is handled by the RELATED/ESTABLISHED traffic rule. The TCP and UDP chains will either accept new incoming connections, or politely reject them. New TCP connections must be started with SYN packets.<br />
<br />
{{Note| NEW but not SYN is the only invalid TCP flag not covered by the INVALID state. The reason is because they are rarely malicious packets, and they should not just be dropped. Instead, we simply do not accept them, so they are rejected with a TCP RST by the next rule.}}<br />
<br />
# iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
# iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP<br />
<br />
We reject TCP connections with TCP RST packets and UDP streams with ICMP port unreachable messages if the ports are not opened. This imitates default Linux behavior (RFC compliant), and it allows the sender to quickly close the connection and clean up.<br />
<br />
# iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
# iptables -A INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
<br />
For other protocols, we add a final rule to the INPUT chain to reject all remaining incoming traffic with icmp protocol unreachable messages. This imitates Linux's default behavior.<br />
<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Example iptables.rules file===<br />
<br />
Example of {{ic|iptables.rules}} file after running all the commands from above:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<br />
# Generated by iptables-save v1.4.18 on Sun Mar 17 14:21:12 2013<br />
*filter<br />
:INPUT DROP [0:0]<br />
:FORWARD DROP [0:0]<br />
:OUTPUT ACCEPT [0:0]<br />
:TCP - [0:0]<br />
:UDP - [0:0]<br />
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
-A INPUT -i lo -j ACCEPT<br />
-A INPUT -m conntrack --ctstate INVALID -j DROP<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP<br />
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
-A INPUT -p tcp -j REJECT --reject-with tcp-reset<br />
-A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
COMMIT<br />
# Completed on Sun Mar 17 14:21:12 2013<br />
}}<br />
<br />
This file can be generated with:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and can be used to prevent blocking yourself out if you are setting up the firewall remotely, just remember to append this line to allow SSH connections on port 22:<br />
<br />
-A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
=== The TCP and UDP chains ===<br />
<br />
The TCP and UDP chains contain rules for accepting new incoming TCP connections and UDP streams to specific ports.<br />
<br />
{{Note|This is where you need to add rules to accept incoming connections, such as SSH, HTTP or other services that you want to access remotely.}}<br />
<br />
==== Opening ports to incoming connections ====<br />
<br />
To accept incoming TCP connections on port 80 for a web server:<br />
<br />
# iptables -A TCP -p tcp --dport 80 -j ACCEPT<br />
<br />
To accept incoming TCP connections on port 443 for a web server (HTTPS):<br />
<br />
# iptables -A TCP -p tcp --dport 443 -j ACCEPT<br />
<br />
To allow remote SSH connections (on port 22):<br />
<br />
# iptables -A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
To accept incoming UDP streams on port 53 for a DNS server:<br />
<br />
# iptables -A UDP -p udp --dport 53 -j ACCEPT<br />
<br />
See {{Ic|man iptables}} for more advanced rules, like matching multiple ports.<br />
<br />
==== Port knocking ====<br />
Port knocking is a method to externally open ports that, by default, the firewall keeps closed. It works by requiring connection attempts to a series of predefined closed ports. When the correct sequence of port "knocks" (connection attempts) is received, the firewall opens certain port(s) to allow a connection. See [[Port Knocking]] for more information.<br />
<br />
=== Protection against spoofing attacks ===<br />
<br />
{{Note|{{ic|rp_filter}} is currently set to {{ic|1}} by default in {{ic|/usr/lib/sysctl.d/50-default.conf}}, so the following step is not necessary.}}<br />
<br />
Blocking reserved local addresses incoming from the internet or local network is normally done through setting the {{Ic|rp_filter}} sysctl to 1. To do so, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details) to enable source address verification which is built into Linux kernel itself. The verification by the kernel will handle spoofing better than individual iptables rules for each case.<br />
<br />
net.ipv4.conf.all.rp_filter=1<br />
<br />
Only when asynchronous routing or {{ic|1=rp_filter=0}} is used, extra checks are necessary:<br />
<br />
# iptables -I INPUT ! -i lo -s 127.0.0.0/8 -j DROP<br />
<br />
=== "Hide" your computer ===<br />
<br />
If you are running a desktop machine, it might be a good idea to block some incoming requests.<br />
<br />
==== Block ping request ====<br />
<br />
A 'Ping' request is an ICMP packet sent to the destination address to ensure connectivity between the devices. If your network works well, you can safely block all ping requests. It is important to note that this ''does not'' actually hide your computer — any packet sent to you is rejected, so you will still show up in a simple nmap "ping scan" of an IP range.<br />
<br />
This is rudimentary "protection" and makes life difficult when debugging issues in the future. You should only do this for education purposes.<br />
<br />
To block echo requests, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details):<br />
<br />
net.ipv4.icmp_echo_ignore_all = 1<br />
<br />
Rate-limiting is a better way to control possible abuse. This first method implements a global limit (ie, only X packets per minute for all source addresses):<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 30/min --limit-burst 8 -j ACCEPT<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP<br />
<br />
Or using the 'recent' module, you can impose a limit per source address:<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --set<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --update --hitcount 6 --seconds 4 -j DROP<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT<br />
<br />
If you choose to use either the rate limiting or the source limiting rules the PING rule that already exists in the INPUT chain needs to be deleted. This can be done as shown below, or alternatively don't use it in the first place. <br />
# iptables -D INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Next you need to decide where you wish to place the rate limiting or source limiting rules. If you place the rules below the RELATED,ESTABLISHED rule then you will be counting and limiting new ping connections, not each ping sent to your machine. If you place them before the RELATED,ESTABLISHED rule then these rules will count and limit each ping sent to your machine, not each ping connection made. <br />
<br />
More information is in the iptables man page, or reading the docs and examples on the webpage http://snowman.net/projects/ipt_recent/<br />
<br />
==== Tricking port scanners ====<br />
<br />
{{Note|This opens you up to a form of [[Wikipedia:Denial-of-service attack|DoS]]. An attack can send packets with spoofed IPs and get them blocked from connecting to your services.}}<br />
<br />
Port scans are used by attackers to identify open ports on your computer. This allows them to identify and fingerprint your running services and possibly launch exploits against them.<br />
<br />
The INVALID state rule will take care of every type of port scan except UDP, ACK and SYN scans (-sU, -sA and -sS in nmap respectively). <br />
<br />
''ACK scans'' are not used to identify open ports, but to identify ports filtered by a firewall. Due to the SYN check for all TCP connections with the state NEW, every single packet sent by an ACK scan will be correctly rejected by a TCP RST packet. Some firewalls drop these packets instead, and this allows an attacker to map out the firewall rules.<br />
<br />
The recent module can be used to trick the remaining two types of port scans. The recent module is used to add hosts to a "recent" list which can be used to fingerprint and stop certain types of attacks. Current recent lists can be viewed in {{Ic|/proc/net/xt_recent/}}.<br />
<br />
===== SYN scans =====<br />
<br />
In a SYN scan, the port scanner sends SYN packet to every port. Closed ports return a TCP RST packet, or get dropped by a strict firewall. Open ports return a SYN ACK packet regardless of the presence of a firewall.<br />
<br />
The recent module can be used to keep track of hosts with rejected connection attempts and return a TCP RST for any SYN packet they send to open ports as if the port was closed. If an open port is the first to be scanned, a SYN ACK will still be returned, so running applications such as ssh on non-standard ports is required for this to work consistently.<br />
<br />
First, insert a rule at the top of the TCP chain. This rule responds with a TCP RST to any host that got onto the TCP-PORTSCAN list in the past sixty seconds. The {{Ic|--update}} switch causes the recent list to be updated, meaning the 60 second counter is reset.<br />
<br />
# iptables -I TCP -p tcp -m recent --update --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
Next, the rule for rejecting TCP packets need to be modified to add hosts with rejected packets to the TCP-PORTSCAN list.<br />
<br />
# iptables -D INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
# iptables -A INPUT -p tcp -m recent --set --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
===== UDP scans =====<br />
<br />
UDP port scans are similar to TCP SYN scans except that UDP is a "connectionless" protocol. There are no handshakes or acknowledgements. Instead, the scanner sends UDP packets to each UDP port. Closed ports should return ICMP port unreachable messages, and open ports do not return a response. Since UDP is not a "reliable" protocol, the scanner has no way of knowing if packets were lost, and has to do multiple checks for each port that does not return a response.<br />
<br />
The Linux kernel sends out ICMP port unreachable messages very slowly, so a full UDP scan against a Linux machine would take over 10 hours. However, common ports could still be identified, so applying the same countermeasures against UDP scans as SYN scans is a good idea.<br />
<br />
First, add a rule to reject packets from hosts on the UDP-PORTSCAN list to the top of the UDP chain.<br />
<br />
# iptables -I UDP -p udp -m recent --update --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with port-unreach<br />
<br />
Next, modify the reject packets rule for UDP:<br />
<br />
# iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreach<br />
# iptables -A INPUT -p udp -m recent --set --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreach<br />
<br />
===== Restore the Final Rule =====<br />
<br />
If either or both of the portscanning tricks above were used the final default rule is no longer the last rule in the INPUT chain. It needs to be the last rule otherwise it will intercept the trick port scanner rules you just added and they will never be used. Simply delete the rule (-D), then add it once again using append (-A) which will place it at the end of the chain.<br />
<br />
# iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Protection against other attacks ===<br />
<br />
See the [[Sysctl#TCP/IP stack hardening|TCP/IP stack hardening]] guide for relevant kernel parameters.<br />
<br />
==== Bruteforce attacks ====<br />
<br />
Unfortunately, bruteforce attacks on services accessible via an external IP address are common. One reason for this is that the attacks are easy to do with the many tools available. Fortunately, there are a number of ways to protect the services against them. One is the use of appropriate {{ic|iptables}} rules which activate and blacklist an IP after a set number of packets attempt to initiate a connection. Another is the use of specialised daemons that monitor the logfiles for failed attempts and blacklist accordingly. <br />
{{Warning| Using an IP blacklist will stop trivial attacks but it relies on an additional daemon and successful logging (the partition containing /var can become full, especially if an attacker is pounding on the server). Additionally, if the attacker knows your IP address, they can send packets with a spoofed source header and get you locked out of the server. [[SSH keys]] provide an elegant solution to the problem of brute forcing without these problems.}}<br />
Two packages that ban IPs after too many password failures are [[Fail2ban]] or, for {{ic|sshd}} in particular, [[Sshguard]]. These two applications update iptables rules to reject future connections from blacklisted IP addresses.<br />
<br />
The following rules give an example configuration to mitigate SSH bruteforce attacks using {{ic|iptables}}.<br />
<br />
# iptables -N IN_SSH<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP <br />
# iptables -A IN_SSH -m recent --name sshbf --set -j ACCEPT<br />
<br />
Most of the options should be self-explanatory, they allow for three connection packets in ten seconds. Further tries in that time will blacklist the IP. The next rule adds a quirk by allowing a total of four attempts in 30 minutes. This is done because some bruteforce attacks are actually performed slow and not in a burst of attempts. The rules employ a number of additional options. To read more about them, check the original reference for this example: [http://compilefailure.blogspot.com/2011/04/better-ssh-brute-force-prevention-with.html compilefailure.blogspot.com]<br />
<br />
Using the above rules, now ensure that:<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
is in an appropriate position in the iptables.rules file. <br />
<br />
This arrangement works for the IN_SSH rule if you followed this entire wiki so far:<br />
*<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j IN_SSH<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
*<br />
<br />
The above rules can, of course, be used to protect any service, though protecting the SSH daemon is probably the most often required one.<br />
<br />
{{Tip|For self-testing the rules after setup, the actual blacklist happening can slow the test making it difficult to fine-tune parameters. One can watch the incoming attempts via {{ic|cat /proc/net/xt_recent/sshbf}}. To unblock the own IP during testing, root is needed {{ic|# echo / > /proc/net/xt_recent/sshbf}}}}<br />
<br />
=== Saving the rules ===<br />
<br />
The ruleset is now finished and should be saved to your hard drive so that it can be loaded on every boot.<br />
<br />
The systemd unit file points to the location where the rule configuration will be saved:<br />
<br />
iptables=/etc/iptables/iptables.rules<br />
ip6tables=/etc/iptables/ip6tables.rules<br />
<br />
Save the rules with this command:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded on boot enabling the '''iptables''' [[daemon]].<br />
<br />
Check that the rules load correctly using:<br />
<br />
# systemctl start iptables.service && systemctl status iptables.service<br />
<br />
=== IPv6 ===<br />
<br />
If you do not use IPv6 (most ISPs do not support it), you should [[Disabling IPv6|disable it]].<br />
<br />
Otherwise, you should enable the firewall rules for IPv6. Just copy '''/etc/iptables/iptables.rules''' to '''/etc/iptables/ip6tables.rules''' and change IPs from v4 format to v6 format and change reject messages from <br />
--reject-with icmp-port-unreachable<br />
to<br />
--reject-with icmp6-port-unreachable<br />
etc.<br />
<br />
Please be aware that '''--reject-with icmp6-proto-unreachable''' does not exist for ICMPv6, so you may reject without any message. (Does anyone know what message would be correct? communication-prohibited? port-unreachable?).<br />
<br />
Netfilter conntrack does not appear to track ICMPv6 Neighbor Discovery Protocol (the IPv6 equivalent of ARP), so we need to allow ICMPv6 traffic regardless of state for all directly attached subnets. The following should be inserted after dropping --ctstate INVALID, but before any other DROP or REJECT targets, along with a corresponding line for each direclty attached subnet:<br />
<br />
ip6tables -A INPUT -s fe80::/64 -p icmpv6 -j ACCEPT<br />
<br />
Since there is no kernel reverse path filter for IPv6, you may want to enable one in ip6tables with the folowing (The first rule is necessary to retain usually needed link local ICMPv6 multicasts):<br />
<br />
ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/64 -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -j DROP<br />
<br />
Now you need to enable the '''ip6tables''' service using [[systemd]].<br />
<br />
== Setting up a NAT gateway ==<br />
<br />
This section of the guide deals with NAT gateways. It is assumed that you already read the [[#Firewall for a single machine|first part of the guide]] and set up the '''INPUT''', '''OUTPUT''', '''TCP''' and '''UDP''' chains like described above. All rules so far have been created in the '''filter''' table. In this section, we will also have to use the '''nat''' table.<br />
<br />
=== Setting up the filter table ===<br />
<br />
==== Creating necessary chains ====<br />
<br />
In our setup, we will use another two chains in the filter table, the '''fw-interfaces''' and '''fw-open''' chains. Create them with the commands<br />
<br />
# iptables -N fw-interfaces<br />
# iptables -N fw-open<br />
<br />
==== Setting up the FORWARD chain ====<br />
<br />
Setting up the '''FORWARD''' chain is similar to the '''INPUT''' chain in the first section.<br />
<br />
Now we set up a rule with the '''conntrack''' match, identical to the one in the '''INPUT''' chain:<br />
<br />
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The next step is to enable forwarding for trusted interfaces and to make all packets pass the '''fw-open''' chain.<br />
<br />
# iptables -A FORWARD -j fw-interfaces <br />
# iptables -A FORWARD -j fw-open <br />
<br />
The remaining packets are denied with an '''ICMP''' message:<br />
<br />
# iptables -A FORWARD -j REJECT --reject-with icmp-host-unreach<br />
# iptables -P FORWARD DROP<br />
<br />
==== Setting up the fw-interfaces and fw-open chains ====<br />
<br />
The meaning of the '''fw-interfaces''' and '''fw-open''' chains is explained later, when we deal with the '''POSTROUTING''' and '''PREROUTING''' chains in the '''nat''' table, respectively.<br />
<br />
=== Setting up the nat table ===<br />
<br />
All over this section, we assume that the outgoing interface (the one with the public internet IP) is '''ppp0'''. Keep in mind that you have to change the name in all following rules if your outgoing interface has another name.<br />
<br />
==== Setting up the POSTROUTING chain ====<br />
<br />
Now, we have to define who is allowed to connect to the internet. Let's assume we have the subnet '''192.168.0.0/24''' (which means all addresses that are of the form 192.168.0.*) on '''eth0'''. We first need to accept the machines on this interface in the FORWARD table, that is why we created the '''fw-interfaces''' chain above:<br />
<br />
# iptables -A fw-interfaces -i eth0 -j ACCEPT<br />
<br />
Now, we have to alter all outgoing packets so that they have our public IP address as the source address, instead of the local LAN address. To do this, we use the '''MASQUERADE''' target:<br />
<br />
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE<br />
<br />
Do not forget the '''-o ppp0''' parameter above. If you omit it, your network will be screwed up.<br />
<br />
Let's assume we have another subnet, '''10.3.0.0/16''' (which means all addresses 10.3.*.*), on the interface '''eth1'''. We add the same rules as above again:<br />
<br />
# iptables -A fw-interfaces -i eth1 -j ACCEPT<br />
# iptables -t nat -A POSTROUTING -s 10.3.0.0/16 -o ppp0 -j MASQUERADE<br />
<br />
The last step is to enable IP Forwarding (if it is not already enabled):<br />
<br />
# echo 1 > /proc/sys/net/ipv4/ip_forward<br />
<br />
Then edit the relevant line in {{ic|/etc/sysctl.d/90-firewall.conf}} so it persists through reboot (see [[sysctl]] for details):<br />
<br />
net.ipv4.ip_forward = 1<br />
<br />
Machines from these subnets can now use your new NAT machine as their gateway. Note that you may want to set up a DNS and DHCP server like '''dnsmasq''' or a combination of '''bind''' and '''dhcpd''' to simplify network settings DNS resolution on the client machines. This is not the topic of this guide.<br />
<br />
==== Setting up the PREROUTING chain ====<br />
<br />
Sometimes, we want to change the address of an incoming packet from the gateway to a LAN machine. To do this, we use the '''fw-open''' chain defined above, as well as the '''PREROUTING''' chain in the '''nat''' table<br />
<br />
I will give two simple examples: First, we want to change all incoming SSH packets (port 22) to the ssh server in the machine '''192.168.0.5''':<br />
<br />
# iptables -A fw-open -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT --to 192.168.0.5<br />
<br />
The second example will show you how to change packets to a different port than the incoming port. We want to change any incoming connection on port '''8000''' to our web server on '''192.168.0.6''', port '''80''':<br />
<br />
# iptables -A fw-open -d 192.168.0.6 -p tcp --dport 80 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to 192.168.0.6:80<br />
<br />
The same setup also works with udp packets.<br />
<br />
=== Saving the rules ===<br />
<br />
Save the rules:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded when you boot enabling the '''iptables''' [[daemon]].<br />
<br />
== See Also ==<br />
<br />
*[[Internet sharing]]<br />
*[[Router]]<br />
*[[Firewalls]]<br />
*[[Uncomplicated Firewall]]<br />
*[http://www.webhostingtalk.com/showthread.php?t=456571 Methods to block SSH attacks]<br />
*[http://www.ducea.com/2006/06/28/using-iptables-to-block-brute-force-attacks/ Using iptables to block brute force attacks]<br />
*[http://linuxconfig.org/collection-of-basic-linux-firewall-iptables-rules 20 Iptables Examples For New SysAdmins]<br />
*[http://www.thegeekstuff.com/2011/06/iptables-rules-examples/ 25 Most Frequently Used Linux IPTables Rules Examples]</div>Branchhttps://wiki.archlinux.org/index.php?title=Simple_stateful_firewall&diff=307731Simple stateful firewall2014-03-31T06:00:29Z<p>Branch: /* IPv6 */ Added rule to fix IPv6 NDP</p>
<hr />
<div>[[Category:Firewalls]]<br />
[[ru:Simple stateful firewall]]<br />
This page explains how to set up a stateful firewall using [[iptables]]. It also explains what the rules mean and why they are needed. For simplicity, it is split into two major sections. The first section deals with a firewall for a single machine, the second sets up a NAT gateway in addition to the firewall from the first section.<br />
<br />
{{Warning| The rules are given in the order that they are executed. If you are logged into a remote machine, you may be locked out of the machine while setting up the rules. You should only follow the steps below while you are logged in locally.<br />
<br />
The [https://wiki.archlinux.org/index.php/Simple_Stateful_Firewall#Example_iptables.rules_file example config file] can be used to get around this problem.<br />
}}<br />
<br />
== Prerequisites ==<br />
<br />
{{Note|Your kernel needs to be compiled with iptables support. All stock Arch Linux kernels have iptables support.}}<br />
<br />
First, install the userland utilities {{Pkg|iptables}} or verify that they are already installed.<br />
<br />
This article assumes that there are currently no iptables rules set. To check the current ruleset and verify that there are currently no rules run the following:<br />
<br />
{{hc|# iptables-save|<nowiki><br />
# Generated by iptables-save v1.4.19.1 on Thu Aug 1 19:28:53 2013<br />
*filter<br />
:INPUT ACCEPT [50:3763]<br />
:FORWARD ACCEPT [0:0]<br />
:OUTPUT ACCEPT [30:3472]<br />
COMMIT<br />
# Completed on Thu Aug 1 19:28:53 2013<br />
</nowiki>}}<br />
<br />
or<br />
<br />
{{hc|# iptables -nvL --line-numbers|<nowiki><br />
Chain INPUT (policy ACCEPT 156 packets, 12541 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain OUTPUT (policy ACCEPT 82 packets, 8672 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
</nowiki>}}<br />
<br />
If there are rules, you may be able to reset the rules by loading a default rule set:<br />
<br />
# iptables-restore < /etc/iptables/empty.rules<br />
<br />
Otherwise, see [[Iptables#Resetting_rules]].<br />
<br />
== Firewall for a single machine ==<br />
<br />
{{Note|Because iptables processes rules in linear order, from top to bottom within a chain, it is advised to put frequently-hit rules near the start of the chain. Of course there is a limit, depending on the logic that is being implemented. Also, rules have an associated runtime cost, so rules should not be reordered solely based upon empirical observations of the byte/packet counters.}}<br />
<br />
=== Creating necessary chains ===<br />
<br />
For this basic setup, we will create two user-defined chains that we will use to open up ports in the firewall.<br />
<br />
# iptables -N TCP<br />
# iptables -N UDP<br />
<br />
The chains can of course have arbitrary names. We pick these just to match the protocols we want handle with them in the later rules, which are specified with the protocol options, e.g. {{ic|-p tcp}}, always.<br />
<br />
=== The FORWARD chain ===<br />
<br />
If you want to set up your machine as a NAT gateway, please look at the [[#Setting up a NAT gateway|second section of this guide]]. For a single machine, however, we simply set the policy of the '''FORWARD''' chain to '''DROP''' and move on:<br />
<br />
# iptables -P FORWARD DROP<br />
<br />
=== The OUTPUT chain ===<br />
<br />
We have no intention of filtering any outgoing traffic, as this would make the setup much more complicated and would require some extra thought. In this simple case, we set the '''OUTPUT''' policy to '''ACCEPT'''.<br />
<br />
# iptables -P OUTPUT ACCEPT<br />
<br />
=== The INPUT chain ===<br />
<br />
First, we set the default policy for the '''INPUT''' chain to '''DROP''' in case something somehow slips by our rules. Dropping all traffic and specifying what is allowed is the best way to make a secure firewall.<br />
{{Warning|This is the step where you will be locked out if you are logged in via SSH. Therefore do this step following your rule regarding port 22 (or whatever port you're using for SSH) to prevent being locked out.}}<br />
<br />
# iptables -P INPUT DROP<br />
<br />
Every packet that is received by any network interface will pass the '''INPUT''' chain first, if it is destined for this machine. In this chain, we make sure that only the packets that we want are accepted.<br />
<br />
The first rule will allow traffic that belongs to established connections, or new valid traffic that is related to these connections such as ICMP errors, or echo replies (the packets a host returns when pinged). '''ICMP''' stands for '''Internet Control Message Protocol'''. Some ICMP messages are very important and help to manage congestion and MTU, and are accepted by this rule.<br />
<br />
# iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The second rule will accept all traffic from the "loopback" (lo) interface, which is necessary for many applications and services.<br />
<br />
{{Note|You can add more trusted interfaces here such as "eth1" if you do not want/need the traffic filtered by the firewall, but be warned that if you have a NAT setup that redirects any kind of traffic to this interface from anywhere else in the network (let's say a router), it'll get through, regardless of any other settings you may have.}}<br />
<br />
# iptables -A INPUT -i lo -j ACCEPT<br />
<br />
The third rule will drop all traffic with an "INVALID" state match. Traffic can fall into four "state" categories: NEW, ESTABLISHED, RELATED or INVALID and this is what makes this a "stateful" firewall rather than a less secure "stateless" one. States are tracked using the "nf_conntrack_*" kernel modules which are loaded automatically by the kernel as you add rules.<br />
<br />
{{Note|<br />
* This rule will drop all packets with invalid headers or checksums, invalid TCP flags, invalid ICMP messages (such as a port unreachable when we did not send anything to the host), and out of sequence packets which can be caused by sequence prediction or other similar attacks. The "DROP" target will drop a packet without any response, contrary to REJECT which politely refuses the packet. We use DROP because there is no proper "REJECT" response to packets that are INVALID, and we do not want to acknowledge that we received these packets.<br />
* ICMPv6 Neighbor Discovery packets remain untracked, and will always be classified "INVALID" though they are not corrupted or the like. Keep this in mind, and accept them before this rule! iptables -A INPUT -p 41 -j ACCEPT<br />
}}<br />
<br />
# iptables -A INPUT -m conntrack --ctstate INVALID -j DROP<br />
<br />
The next rule will accept all new incoming '''ICMP echo requests''', also known as pings. Only the first packet will count as NEW, the rest will be handled by the RELATED,ESTABLISHED rule. Since the computer is not a router, no other ICMP traffic with state NEW needs to be allowed.<br />
<br />
# iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Now we attach the TCP and UDP chains to the INPUT chain to handle all new incoming connections. Once a connection is accepted by either TCP or UDP chain, it is handled by the RELATED/ESTABLISHED traffic rule. The TCP and UDP chains will either accept new incoming connections, or politely reject them. New TCP connections must be started with SYN packets.<br />
<br />
{{Note| NEW but not SYN is the only invalid TCP flag not covered by the INVALID state. The reason is because they are rarely malicious packets, and they should not just be dropped. Instead, we simply do not accept them, so they are rejected with a TCP RST by the next rule.}}<br />
<br />
# iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
# iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP<br />
<br />
We reject TCP connections with TCP RST packets and UDP streams with ICMP port unreachable messages if the ports are not opened. This imitates default Linux behavior (RFC compliant), and it allows the sender to quickly close the connection and clean up.<br />
<br />
# iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
# iptables -A INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
<br />
For other protocols, we add a final rule to the INPUT chain to reject all remaining incoming traffic with icmp protocol unreachable messages. This imitates Linux's default behavior.<br />
<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Example iptables.rules file===<br />
<br />
Example of {{ic|iptables.rules}} file after running all the commands from above:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<br />
# Generated by iptables-save v1.4.18 on Sun Mar 17 14:21:12 2013<br />
*filter<br />
:INPUT DROP [0:0]<br />
:FORWARD DROP [0:0]<br />
:OUTPUT ACCEPT [0:0]<br />
:TCP - [0:0]<br />
:UDP - [0:0]<br />
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
-A INPUT -i lo -j ACCEPT<br />
-A INPUT -m conntrack --ctstate INVALID -j DROP<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP<br />
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
-A INPUT -p tcp -j REJECT --reject-with tcp-reset<br />
-A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
COMMIT<br />
# Completed on Sun Mar 17 14:21:12 2013<br />
}}<br />
<br />
This file can be generated with:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and can be used to prevent blocking yourself out if you are setting up the firewall remotely, just remember to append this line to allow SSH connections on port 22:<br />
<br />
-A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
=== The TCP and UDP chains ===<br />
<br />
The TCP and UDP chains contain rules for accepting new incoming TCP connections and UDP streams to specific ports.<br />
<br />
{{Note|This is where you need to add rules to accept incoming connections, such as SSH, HTTP or other services that you want to access remotely.}}<br />
<br />
==== Opening ports to incoming connections ====<br />
<br />
To accept incoming TCP connections on port 80 for a web server:<br />
<br />
# iptables -A TCP -p tcp --dport 80 -j ACCEPT<br />
<br />
To accept incoming TCP connections on port 443 for a web server (HTTPS):<br />
<br />
# iptables -A TCP -p tcp --dport 443 -j ACCEPT<br />
<br />
To allow remote SSH connections (on port 22):<br />
<br />
# iptables -A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
To accept incoming UDP streams on port 53 for a DNS server:<br />
<br />
# iptables -A UDP -p udp --dport 53 -j ACCEPT<br />
<br />
See {{Ic|man iptables}} for more advanced rules, like matching multiple ports.<br />
<br />
==== Port knocking ====<br />
Port knocking is a method to externally open ports that, by default, the firewall keeps closed. It works by requiring connection attempts to a series of predefined closed ports. When the correct sequence of port "knocks" (connection attempts) is received, the firewall opens certain port(s) to allow a connection. See [[Port Knocking]] for more information.<br />
<br />
=== Protection against spoofing attacks ===<br />
<br />
{{Note|{{ic|rp_filter}} is currently set to {{ic|1}} by default in {{ic|/usr/lib/sysctl.d/50-default.conf}}, so the following step is not necessary.}}<br />
<br />
Blocking reserved local addresses incoming from the internet or local network is normally done through setting the {{Ic|rp_filter}} sysctl to 1. To do so, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details) to enable source address verification which is built into Linux kernel itself. The verification by the kernel will handle spoofing better than individual iptables rules for each case.<br />
<br />
net.ipv4.conf.all.rp_filter=1<br />
<br />
Only when asynchronous routing or {{ic|1=rp_filter=0}} is used, extra checks are necessary:<br />
<br />
# iptables -I INPUT ! -i lo -s 127.0.0.0/8 -j DROP<br />
<br />
=== "Hide" your computer ===<br />
<br />
If you are running a desktop machine, it might be a good idea to block some incoming requests.<br />
<br />
==== Block ping request ====<br />
<br />
A 'Ping' request is an ICMP packet sent to the destination address to ensure connectivity between the devices. If your network works well, you can safely block all ping requests. It is important to note that this ''does not'' actually hide your computer — any packet sent to you is rejected, so you will still show up in a simple nmap "ping scan" of an IP range.<br />
<br />
This is rudimentary "protection" and makes life difficult when debugging issues in the future. You should only do this for education purposes.<br />
<br />
To block echo requests, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details):<br />
<br />
net.ipv4.icmp_echo_ignore_all = 1<br />
<br />
Rate-limiting is a better way to control possible abuse. This first method implements a global limit (ie, only X packets per minute for all source addresses):<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 30/min --limit-burst 8 -j ACCEPT<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP<br />
<br />
Or using the 'recent' module, you can impose a limit per source address:<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --set<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --update --hitcount 6 --seconds 4 -j DROP<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT<br />
<br />
If you choose to use either the rate limiting or the source limiting rules the PING rule that already exists in the INPUT chain needs to be deleted. This can be done as shown below, or alternatively don't use it in the first place. <br />
# iptables -D INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Next you need to decide where you wish to place the rate limiting or source limiting rules. If you place the rules below the RELATED,ESTABLISHED rule then you will be counting and limiting new ping connections, not each ping sent to your machine. If you place them before the RELATED,ESTABLISHED rule then these rules will count and limit each ping sent to your machine, not each ping connection made. <br />
<br />
More information is in the iptables man page, or reading the docs and examples on the webpage http://snowman.net/projects/ipt_recent/<br />
<br />
==== Tricking port scanners ====<br />
<br />
{{Note|This opens you up to a form of [[Wikipedia:Denial-of-service attack|DoS]]. An attack can send packets with spoofed IPs and get them blocked from connecting to your services.}}<br />
<br />
Port scans are used by attackers to identify open ports on your computer. This allows them to identify and fingerprint your running services and possibly launch exploits against them.<br />
<br />
The INVALID state rule will take care of every type of port scan except UDP, ACK and SYN scans (-sU, -sA and -sS in nmap respectively). <br />
<br />
''ACK scans'' are not used to identify open ports, but to identify ports filtered by a firewall. Due to the SYN check for all TCP connections with the state NEW, every single packet sent by an ACK scan will be correctly rejected by a TCP RST packet. Some firewalls drop these packets instead, and this allows an attacker to map out the firewall rules.<br />
<br />
The recent module can be used to trick the remaining two types of port scans. The recent module is used to add hosts to a "recent" list which can be used to fingerprint and stop certain types of attacks. Current recent lists can be viewed in {{Ic|/proc/net/xt_recent/}}.<br />
<br />
===== SYN scans =====<br />
<br />
In a SYN scan, the port scanner sends SYN packet to every port. Closed ports return a TCP RST packet, or get dropped by a strict firewall. Open ports return a SYN ACK packet regardless of the presence of a firewall.<br />
<br />
The recent module can be used to keep track of hosts with rejected connection attempts and return a TCP RST for any SYN packet they send to open ports as if the port was closed. If an open port is the first to be scanned, a SYN ACK will still be returned, so running applications such as ssh on non-standard ports is required for this to work consistently.<br />
<br />
First, insert a rule at the top of the TCP chain. This rule responds with a TCP RST to any host that got onto the TCP-PORTSCAN list in the past sixty seconds. The {{Ic|--update}} switch causes the recent list to be updated, meaning the 60 second counter is reset.<br />
<br />
# iptables -I TCP -p tcp -m recent --update --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
Next, the rule for rejecting TCP packets need to be modified to add hosts with rejected packets to the TCP-PORTSCAN list.<br />
<br />
# iptables -D INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
# iptables -A INPUT -p tcp -m recent --set --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
===== UDP scans =====<br />
<br />
UDP port scans are similar to TCP SYN scans except that UDP is a "connectionless" protocol. There are no handshakes or acknowledgements. Instead, the scanner sends UDP packets to each UDP port. Closed ports should return ICMP port unreachable messages, and open ports do not return a response. Since UDP is not a "reliable" protocol, the scanner has no way of knowing if packets were lost, and has to do multiple checks for each port that does not return a response.<br />
<br />
The Linux kernel sends out ICMP port unreachable messages very slowly, so a full UDP scan against a Linux machine would take over 10 hours. However, common ports could still be identified, so applying the same countermeasures against UDP scans as SYN scans is a good idea.<br />
<br />
First, add a rule to reject packets from hosts on the UDP-PORTSCAN list to the top of the UDP chain.<br />
<br />
# iptables -I UDP -p udp -m recent --update --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with port-unreach<br />
<br />
Next, modify the reject packets rule for UDP:<br />
<br />
# iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreach<br />
# iptables -A INPUT -p udp -m recent --set --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreach<br />
<br />
===== Restore the Final Rule =====<br />
<br />
If either or both of the portscanning tricks above were used the final default rule is no longer the last rule in the INPUT chain. It needs to be the last rule otherwise it will intercept the trick port scanner rules you just added and they will never be used. Simply delete the rule (-D), then add it once again using append (-A) which will place it at the end of the chain.<br />
<br />
# iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Protection against other attacks ===<br />
<br />
See the [[Sysctl#TCP/IP stack hardening|TCP/IP stack hardening]] guide for relevant kernel parameters.<br />
<br />
==== Bruteforce attacks ====<br />
<br />
Unfortunately, bruteforce attacks on services accessible via an external IP address are common. One reason for this is that the attacks are easy to do with the many tools available. Fortunately, there are a number of ways to protect the services against them. One is the use of appropriate {{ic|iptables}} rules which activate and blacklist an IP after a set number of packets attempt to initiate a connection. Another is the use of specialised daemons that monitor the logfiles for failed attempts and blacklist accordingly. <br />
{{Warning| Using an IP blacklist will stop trivial attacks but it relies on an additional daemon and successful logging (the partition containing /var can become full, especially if an attacker is pounding on the server). Additionally, if the attacker knows your IP address, they can send packets with a spoofed source header and get you locked out of the server. [[SSH keys]] provide an elegant solution to the problem of brute forcing without these problems.}}<br />
Two packages that ban IPs after too many password failures are [[Fail2ban]] or, for {{ic|sshd}} in particular, [[Sshguard]]. These two applications update iptables rules to reject future connections from blacklisted IP addresses.<br />
<br />
The following rules give an example configuration to mitigate SSH bruteforce attacks using {{ic|iptables}}.<br />
<br />
# iptables -N IN_SSH<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP <br />
# iptables -A IN_SSH -m recent --name sshbf --set -j ACCEPT<br />
<br />
Most of the options should be self-explanatory, they allow for three connection packets in ten seconds. Further tries in that time will blacklist the IP. The next rule adds a quirk by allowing a total of four attempts in 30 minutes. This is done because some bruteforce attacks are actually performed slow and not in a burst of attempts. The rules employ a number of additional options. To read more about them, check the original reference for this example: [http://compilefailure.blogspot.com/2011/04/better-ssh-brute-force-prevention-with.html compilefailure.blogspot.com]<br />
<br />
Using the above rules, now ensure that:<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
is in an appropriate position in the iptables.rules file. <br />
<br />
This arrangement works for the IN_SSH rule if you followed this entire wiki so far:<br />
*<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j IN_SSH<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
*<br />
<br />
The above rules can, of course, be used to protect any service, though protecting the SSH daemon is probably the most often required one.<br />
<br />
{{Tip|For self-testing the rules after setup, the actual blacklist happening can slow the test making it difficult to fine-tune parameters. One can watch the incoming attempts via {{ic|cat /proc/net/xt_recent/sshbf}}. To unblock the own IP during testing, root is needed {{ic|# echo / > /proc/net/xt_recent/sshbf}}}}<br />
<br />
=== Saving the rules ===<br />
<br />
The ruleset is now finished and should be saved to your hard drive so that it can be loaded on every boot.<br />
<br />
The systemd unit file points to the location where the rule configuration will be saved:<br />
<br />
iptables=/etc/iptables/iptables.rules<br />
ip6tables=/etc/iptables/ip6tables.rules<br />
<br />
Save the rules with this command:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded on boot enabling the '''iptables''' [[daemon]].<br />
<br />
Check that the rules load correctly using:<br />
<br />
# systemctl start iptables.service && systemctl status iptables.service<br />
<br />
=== IPv6 ===<br />
<br />
If you do not use IPv6 (most ISPs do not support it), you should [[Disabling IPv6|disable it]].<br />
<br />
Otherwise, you should enable the firewall rules for IPv6. Just copy '''/etc/iptables/iptables.rules''' to '''/etc/iptables/ip6tables.rules''' and change IPs from v4 format to v6 format and change reject messages from <br />
--reject-with icmp-port-unreachable<br />
to<br />
--reject-with icmp6-port-unreachable<br />
etc.<br />
<br />
Please be aware that '''--reject-with icmp6-proto-unreachable''' does not exist for ICMPv6, so you may reject without any message. (Does anyone know what message would be correct? communication-prohibited? port-unreachable?).<br />
<br />
Netfilter conntrack does not appear to track ICMPv6 Neighbor Discovery Protocol (the IPv6 equivalent of ARP), so we need to allow ICMPv6 traffic regardless of state for all directly attached subnets. The following should be inserted after dropping --ctstate INVALID, but before any other DROP or REJECT targets, along with a corresponding line for each direclty attached subnet:<br />
<br />
iptables -A INPUT -s fe80::/64 -p icmpv6 -j ACCEPT<br />
<br />
Since there is no kernel reverse path filter for IPv6, you may want to enable one in ip6tables with the folowing (The first rule is necessary to retain usually needed link local ICMPv6 multicasts):<br />
<br />
ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/64 -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -j DROP<br />
<br />
Now you need to enable the '''ip6tables''' service using [[systemd]].<br />
<br />
== Setting up a NAT gateway ==<br />
<br />
This section of the guide deals with NAT gateways. It is assumed that you already read the [[#Firewall for a single machine|first part of the guide]] and set up the '''INPUT''', '''OUTPUT''', '''TCP''' and '''UDP''' chains like described above. All rules so far have been created in the '''filter''' table. In this section, we will also have to use the '''nat''' table.<br />
<br />
=== Setting up the filter table ===<br />
<br />
==== Creating necessary chains ====<br />
<br />
In our setup, we will use another two chains in the filter table, the '''fw-interfaces''' and '''fw-open''' chains. Create them with the commands<br />
<br />
# iptables -N fw-interfaces<br />
# iptables -N fw-open<br />
<br />
==== Setting up the FORWARD chain ====<br />
<br />
Setting up the '''FORWARD''' chain is similar to the '''INPUT''' chain in the first section.<br />
<br />
Now we set up a rule with the '''conntrack''' match, identical to the one in the '''INPUT''' chain:<br />
<br />
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The next step is to enable forwarding for trusted interfaces and to make all packets pass the '''fw-open''' chain.<br />
<br />
# iptables -A FORWARD -j fw-interfaces <br />
# iptables -A FORWARD -j fw-open <br />
<br />
The remaining packets are denied with an '''ICMP''' message:<br />
<br />
# iptables -A FORWARD -j REJECT --reject-with icmp-host-unreach<br />
# iptables -P FORWARD DROP<br />
<br />
==== Setting up the fw-interfaces and fw-open chains ====<br />
<br />
The meaning of the '''fw-interfaces''' and '''fw-open''' chains is explained later, when we deal with the '''POSTROUTING''' and '''PREROUTING''' chains in the '''nat''' table, respectively.<br />
<br />
=== Setting up the nat table ===<br />
<br />
All over this section, we assume that the outgoing interface (the one with the public internet IP) is '''ppp0'''. Keep in mind that you have to change the name in all following rules if your outgoing interface has another name.<br />
<br />
==== Setting up the POSTROUTING chain ====<br />
<br />
Now, we have to define who is allowed to connect to the internet. Let's assume we have the subnet '''192.168.0.0/24''' (which means all addresses that are of the form 192.168.0.*) on '''eth0'''. We first need to accept the machines on this interface in the FORWARD table, that is why we created the '''fw-interfaces''' chain above:<br />
<br />
# iptables -A fw-interfaces -i eth0 -j ACCEPT<br />
<br />
Now, we have to alter all outgoing packets so that they have our public IP address as the source address, instead of the local LAN address. To do this, we use the '''MASQUERADE''' target:<br />
<br />
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE<br />
<br />
Do not forget the '''-o ppp0''' parameter above. If you omit it, your network will be screwed up.<br />
<br />
Let's assume we have another subnet, '''10.3.0.0/16''' (which means all addresses 10.3.*.*), on the interface '''eth1'''. We add the same rules as above again:<br />
<br />
# iptables -A fw-interfaces -i eth1 -j ACCEPT<br />
# iptables -t nat -A POSTROUTING -s 10.3.0.0/16 -o ppp0 -j MASQUERADE<br />
<br />
The last step is to enable IP Forwarding (if it is not already enabled):<br />
<br />
# echo 1 > /proc/sys/net/ipv4/ip_forward<br />
<br />
Then edit the relevant line in {{ic|/etc/sysctl.d/90-firewall.conf}} so it persists through reboot (see [[sysctl]] for details):<br />
<br />
net.ipv4.ip_forward = 1<br />
<br />
Machines from these subnets can now use your new NAT machine as their gateway. Note that you may want to set up a DNS and DHCP server like '''dnsmasq''' or a combination of '''bind''' and '''dhcpd''' to simplify network settings DNS resolution on the client machines. This is not the topic of this guide.<br />
<br />
==== Setting up the PREROUTING chain ====<br />
<br />
Sometimes, we want to change the address of an incoming packet from the gateway to a LAN machine. To do this, we use the '''fw-open''' chain defined above, as well as the '''PREROUTING''' chain in the '''nat''' table<br />
<br />
I will give two simple examples: First, we want to change all incoming SSH packets (port 22) to the ssh server in the machine '''192.168.0.5''':<br />
<br />
# iptables -A fw-open -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT --to 192.168.0.5<br />
<br />
The second example will show you how to change packets to a different port than the incoming port. We want to change any incoming connection on port '''8000''' to our web server on '''192.168.0.6''', port '''80''':<br />
<br />
# iptables -A fw-open -d 192.168.0.6 -p tcp --dport 80 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to 192.168.0.6:80<br />
<br />
The same setup also works with udp packets.<br />
<br />
=== Saving the rules ===<br />
<br />
Save the rules:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded when you boot enabling the '''iptables''' [[daemon]].<br />
<br />
== See Also ==<br />
<br />
*[[Internet sharing]]<br />
*[[Router]]<br />
*[[Firewalls]]<br />
*[[Uncomplicated Firewall]]<br />
*[http://www.webhostingtalk.com/showthread.php?t=456571 Methods to block SSH attacks]<br />
*[http://www.ducea.com/2006/06/28/using-iptables-to-block-brute-force-attacks/ Using iptables to block brute force attacks]<br />
*[http://linuxconfig.org/collection-of-basic-linux-firewall-iptables-rules 20 Iptables Examples For New SysAdmins]<br />
*[http://www.thegeekstuff.com/2011/06/iptables-rules-examples/ 25 Most Frequently Used Linux IPTables Rules Examples]</div>Branchhttps://wiki.archlinux.org/index.php?title=Simple_stateful_firewall&diff=307727Simple stateful firewall2014-03-31T05:06:00Z<p>Branch: /* IPv6 */</p>
<hr />
<div>[[Category:Firewalls]]<br />
[[ru:Simple stateful firewall]]<br />
This page explains how to set up a stateful firewall using [[iptables]]. It also explains what the rules mean and why they are needed. For simplicity, it is split into two major sections. The first section deals with a firewall for a single machine, the second sets up a NAT gateway in addition to the firewall from the first section.<br />
<br />
{{Warning| The rules are given in the order that they are executed. If you are logged into a remote machine, you may be locked out of the machine while setting up the rules. You should only follow the steps below while you are logged in locally.<br />
<br />
The [https://wiki.archlinux.org/index.php/Simple_Stateful_Firewall#Example_iptables.rules_file example config file] can be used to get around this problem.<br />
}}<br />
<br />
== Prerequisites ==<br />
<br />
{{Note|Your kernel needs to be compiled with iptables support. All stock Arch Linux kernels have iptables support.}}<br />
<br />
First, install the userland utilities {{Pkg|iptables}} or verify that they are already installed.<br />
<br />
This article assumes that there are currently no iptables rules set. To check the current ruleset and verify that there are currently no rules run the following:<br />
<br />
{{hc|# iptables-save|<nowiki><br />
# Generated by iptables-save v1.4.19.1 on Thu Aug 1 19:28:53 2013<br />
*filter<br />
:INPUT ACCEPT [50:3763]<br />
:FORWARD ACCEPT [0:0]<br />
:OUTPUT ACCEPT [30:3472]<br />
COMMIT<br />
# Completed on Thu Aug 1 19:28:53 2013<br />
</nowiki>}}<br />
<br />
or<br />
<br />
{{hc|# iptables -nvL --line-numbers|<nowiki><br />
Chain INPUT (policy ACCEPT 156 packets, 12541 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
<br />
Chain OUTPUT (policy ACCEPT 82 packets, 8672 bytes)<br />
num pkts bytes target prot opt in out source destination<br />
</nowiki>}}<br />
<br />
If there are rules, you may be able to reset the rules by loading a default rule set:<br />
<br />
# iptables-restore < /etc/iptables/empty.rules<br />
<br />
Otherwise, see [[Iptables#Resetting_rules]].<br />
<br />
== Firewall for a single machine ==<br />
<br />
{{Note|Because iptables processes rules in linear order, from top to bottom within a chain, it is advised to put frequently-hit rules near the start of the chain. Of course there is a limit, depending on the logic that is being implemented. Also, rules have an associated runtime cost, so rules should not be reordered solely based upon empirical observations of the byte/packet counters.}}<br />
<br />
=== Creating necessary chains ===<br />
<br />
For this basic setup, we will create two user-defined chains that we will use to open up ports in the firewall.<br />
<br />
# iptables -N TCP<br />
# iptables -N UDP<br />
<br />
The chains can of course have arbitrary names. We pick these just to match the protocols we want handle with them in the later rules, which are specified with the protocol options, e.g. {{ic|-p tcp}}, always.<br />
<br />
=== The FORWARD chain ===<br />
<br />
If you want to set up your machine as a NAT gateway, please look at the [[#Setting up a NAT gateway|second section of this guide]]. For a single machine, however, we simply set the policy of the '''FORWARD''' chain to '''DROP''' and move on:<br />
<br />
# iptables -P FORWARD DROP<br />
<br />
=== The OUTPUT chain ===<br />
<br />
We have no intention of filtering any outgoing traffic, as this would make the setup much more complicated and would require some extra thought. In this simple case, we set the '''OUTPUT''' policy to '''ACCEPT'''.<br />
<br />
# iptables -P OUTPUT ACCEPT<br />
<br />
=== The INPUT chain ===<br />
<br />
First, we set the default policy for the '''INPUT''' chain to '''DROP''' in case something somehow slips by our rules. Dropping all traffic and specifying what is allowed is the best way to make a secure firewall.<br />
{{Warning|This is the step where you will be locked out if you are logged in via SSH. Therefore do this step following your rule regarding port 22 (or whatever port you're using for SSH) to prevent being locked out.}}<br />
<br />
# iptables -P INPUT DROP<br />
<br />
Every packet that is received by any network interface will pass the '''INPUT''' chain first, if it is destined for this machine. In this chain, we make sure that only the packets that we want are accepted.<br />
<br />
The first rule will allow traffic that belongs to established connections, or new valid traffic that is related to these connections such as ICMP errors, or echo replies (the packets a host returns when pinged). '''ICMP''' stands for '''Internet Control Message Protocol'''. Some ICMP messages are very important and help to manage congestion and MTU, and are accepted by this rule.<br />
<br />
# iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The second rule will accept all traffic from the "loopback" (lo) interface, which is necessary for many applications and services.<br />
<br />
{{Note|You can add more trusted interfaces here such as "eth1" if you do not want/need the traffic filtered by the firewall, but be warned that if you have a NAT setup that redirects any kind of traffic to this interface from anywhere else in the network (let's say a router), it'll get through, regardless of any other settings you may have.}}<br />
<br />
# iptables -A INPUT -i lo -j ACCEPT<br />
<br />
The third rule will drop all traffic with an "INVALID" state match. Traffic can fall into four "state" categories: NEW, ESTABLISHED, RELATED or INVALID and this is what makes this a "stateful" firewall rather than a less secure "stateless" one. States are tracked using the "nf_conntrack_*" kernel modules which are loaded automatically by the kernel as you add rules.<br />
<br />
{{Note|<br />
* This rule will drop all packets with invalid headers or checksums, invalid TCP flags, invalid ICMP messages (such as a port unreachable when we did not send anything to the host), and out of sequence packets which can be caused by sequence prediction or other similar attacks. The "DROP" target will drop a packet without any response, contrary to REJECT which politely refuses the packet. We use DROP because there is no proper "REJECT" response to packets that are INVALID, and we do not want to acknowledge that we received these packets.<br />
* ICMPv6 Neighbor Discovery packets remain untracked, and will always be classified "INVALID" though they are not corrupted or the like. Keep this in mind, and accept them before this rule! iptables -A INPUT -p 41 -j ACCEPT<br />
}}<br />
<br />
# iptables -A INPUT -m conntrack --ctstate INVALID -j DROP<br />
<br />
The next rule will accept all new incoming '''ICMP echo requests''', also known as pings. Only the first packet will count as NEW, the rest will be handled by the RELATED,ESTABLISHED rule. Since the computer is not a router, no other ICMP traffic with state NEW needs to be allowed.<br />
<br />
# iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Now we attach the TCP and UDP chains to the INPUT chain to handle all new incoming connections. Once a connection is accepted by either TCP or UDP chain, it is handled by the RELATED/ESTABLISHED traffic rule. The TCP and UDP chains will either accept new incoming connections, or politely reject them. New TCP connections must be started with SYN packets.<br />
<br />
{{Note| NEW but not SYN is the only invalid TCP flag not covered by the INVALID state. The reason is because they are rarely malicious packets, and they should not just be dropped. Instead, we simply do not accept them, so they are rejected with a TCP RST by the next rule.}}<br />
<br />
# iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
# iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP<br />
<br />
We reject TCP connections with TCP RST packets and UDP streams with ICMP port unreachable messages if the ports are not opened. This imitates default Linux behavior (RFC compliant), and it allows the sender to quickly close the connection and clean up.<br />
<br />
# iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
# iptables -A INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
<br />
For other protocols, we add a final rule to the INPUT chain to reject all remaining incoming traffic with icmp protocol unreachable messages. This imitates Linux's default behavior.<br />
<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Example iptables.rules file===<br />
<br />
Example of {{ic|iptables.rules}} file after running all the commands from above:<br />
<br />
{{hc|/etc/iptables/iptables.rules|<br />
# Generated by iptables-save v1.4.18 on Sun Mar 17 14:21:12 2013<br />
*filter<br />
:INPUT DROP [0:0]<br />
:FORWARD DROP [0:0]<br />
:OUTPUT ACCEPT [0:0]<br />
:TCP - [0:0]<br />
:UDP - [0:0]<br />
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
-A INPUT -i lo -j ACCEPT<br />
-A INPUT -m conntrack --ctstate INVALID -j DROP<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP<br />
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable<br />
-A INPUT -p tcp -j REJECT --reject-with tcp-reset<br />
-A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
COMMIT<br />
# Completed on Sun Mar 17 14:21:12 2013<br />
}}<br />
<br />
This file can be generated with:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and can be used to prevent blocking yourself out if you are setting up the firewall remotely, just remember to append this line to allow SSH connections on port 22:<br />
<br />
-A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
=== The TCP and UDP chains ===<br />
<br />
The TCP and UDP chains contain rules for accepting new incoming TCP connections and UDP streams to specific ports.<br />
<br />
{{Note|This is where you need to add rules to accept incoming connections, such as SSH, HTTP or other services that you want to access remotely.}}<br />
<br />
==== Opening ports to incoming connections ====<br />
<br />
To accept incoming TCP connections on port 80 for a web server:<br />
<br />
# iptables -A TCP -p tcp --dport 80 -j ACCEPT<br />
<br />
To accept incoming TCP connections on port 443 for a web server (HTTPS):<br />
<br />
# iptables -A TCP -p tcp --dport 443 -j ACCEPT<br />
<br />
To allow remote SSH connections (on port 22):<br />
<br />
# iptables -A TCP -p tcp --dport 22 -j ACCEPT<br />
<br />
To accept incoming UDP streams on port 53 for a DNS server:<br />
<br />
# iptables -A UDP -p udp --dport 53 -j ACCEPT<br />
<br />
See {{Ic|man iptables}} for more advanced rules, like matching multiple ports.<br />
<br />
==== Port knocking ====<br />
Port knocking is a method to externally open ports that, by default, the firewall keeps closed. It works by requiring connection attempts to a series of predefined closed ports. When the correct sequence of port "knocks" (connection attempts) is received, the firewall opens certain port(s) to allow a connection. See [[Port Knocking]] for more information.<br />
<br />
=== Protection against spoofing attacks ===<br />
<br />
{{Note|{{ic|rp_filter}} is currently set to {{ic|1}} by default in {{ic|/usr/lib/sysctl.d/50-default.conf}}, so the following step is not necessary.}}<br />
<br />
Blocking reserved local addresses incoming from the internet or local network is normally done through setting the {{Ic|rp_filter}} sysctl to 1. To do so, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details) to enable source address verification which is built into Linux kernel itself. The verification by the kernel will handle spoofing better than individual iptables rules for each case.<br />
<br />
net.ipv4.conf.all.rp_filter=1<br />
<br />
Only when asynchronous routing or {{ic|1=rp_filter=0}} is used, extra checks are necessary:<br />
<br />
# iptables -I INPUT ! -i lo -s 127.0.0.0/8 -j DROP<br />
<br />
=== "Hide" your computer ===<br />
<br />
If you are running a desktop machine, it might be a good idea to block some incoming requests.<br />
<br />
==== Block ping request ====<br />
<br />
A 'Ping' request is an ICMP packet sent to the destination address to ensure connectivity between the devices. If your network works well, you can safely block all ping requests. It is important to note that this ''does not'' actually hide your computer — any packet sent to you is rejected, so you will still show up in a simple nmap "ping scan" of an IP range.<br />
<br />
This is rudimentary "protection" and makes life difficult when debugging issues in the future. You should only do this for education purposes.<br />
<br />
To block echo requests, add the following line to your {{Ic|/etc/sysctl.d/90-firewall.conf}} file (see [[sysctl]] for details):<br />
<br />
net.ipv4.icmp_echo_ignore_all = 1<br />
<br />
Rate-limiting is a better way to control possible abuse. This first method implements a global limit (ie, only X packets per minute for all source addresses):<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 30/min --limit-burst 8 -j ACCEPT<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP<br />
<br />
Or using the 'recent' module, you can impose a limit per source address:<br />
<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --set<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -m recent --name ping_limiter --update --hitcount 6 --seconds 4 -j DROP<br />
# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT<br />
<br />
If you choose to use either the rate limiting or the source limiting rules the PING rule that already exists in the INPUT chain needs to be deleted. This can be done as shown below, or alternatively don't use it in the first place. <br />
# iptables -D INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
<br />
Next you need to decide where you wish to place the rate limiting or source limiting rules. If you place the rules below the RELATED,ESTABLISHED rule then you will be counting and limiting new ping connections, not each ping sent to your machine. If you place them before the RELATED,ESTABLISHED rule then these rules will count and limit each ping sent to your machine, not each ping connection made. <br />
<br />
More information is in the iptables man page, or reading the docs and examples on the webpage http://snowman.net/projects/ipt_recent/<br />
<br />
==== Tricking port scanners ====<br />
<br />
{{Note|This opens you up to a form of [[Wikipedia:Denial-of-service attack|DoS]]. An attack can send packets with spoofed IPs and get them blocked from connecting to your services.}}<br />
<br />
Port scans are used by attackers to identify open ports on your computer. This allows them to identify and fingerprint your running services and possibly launch exploits against them.<br />
<br />
The INVALID state rule will take care of every type of port scan except UDP, ACK and SYN scans (-sU, -sA and -sS in nmap respectively). <br />
<br />
''ACK scans'' are not used to identify open ports, but to identify ports filtered by a firewall. Due to the SYN check for all TCP connections with the state NEW, every single packet sent by an ACK scan will be correctly rejected by a TCP RST packet. Some firewalls drop these packets instead, and this allows an attacker to map out the firewall rules.<br />
<br />
The recent module can be used to trick the remaining two types of port scans. The recent module is used to add hosts to a "recent" list which can be used to fingerprint and stop certain types of attacks. Current recent lists can be viewed in {{Ic|/proc/net/xt_recent/}}.<br />
<br />
===== SYN scans =====<br />
<br />
In a SYN scan, the port scanner sends SYN packet to every port. Closed ports return a TCP RST packet, or get dropped by a strict firewall. Open ports return a SYN ACK packet regardless of the presence of a firewall.<br />
<br />
The recent module can be used to keep track of hosts with rejected connection attempts and return a TCP RST for any SYN packet they send to open ports as if the port was closed. If an open port is the first to be scanned, a SYN ACK will still be returned, so running applications such as ssh on non-standard ports is required for this to work consistently.<br />
<br />
First, insert a rule at the top of the TCP chain. This rule responds with a TCP RST to any host that got onto the TCP-PORTSCAN list in the past sixty seconds. The {{Ic|--update}} switch causes the recent list to be updated, meaning the 60 second counter is reset.<br />
<br />
# iptables -I TCP -p tcp -m recent --update --seconds 60 --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
Next, the rule for rejecting TCP packets need to be modified to add hosts with rejected packets to the TCP-PORTSCAN list.<br />
<br />
# iptables -D INPUT -p tcp -j REJECT --reject-with tcp-rst<br />
# iptables -A INPUT -p tcp -m recent --set --name TCP-PORTSCAN -j REJECT --reject-with tcp-rst<br />
<br />
===== UDP scans =====<br />
<br />
UDP port scans are similar to TCP SYN scans except that UDP is a "connectionless" protocol. There are no handshakes or acknowledgements. Instead, the scanner sends UDP packets to each UDP port. Closed ports should return ICMP port unreachable messages, and open ports do not return a response. Since UDP is not a "reliable" protocol, the scanner has no way of knowing if packets were lost, and has to do multiple checks for each port that does not return a response.<br />
<br />
The Linux kernel sends out ICMP port unreachable messages very slowly, so a full UDP scan against a Linux machine would take over 10 hours. However, common ports could still be identified, so applying the same countermeasures against UDP scans as SYN scans is a good idea.<br />
<br />
First, add a rule to reject packets from hosts on the UDP-PORTSCAN list to the top of the UDP chain.<br />
<br />
# iptables -I UDP -p udp -m recent --update --seconds 60 --name UDP-PORTSCAN -j REJECT --reject-with port-unreach<br />
<br />
Next, modify the reject packets rule for UDP:<br />
<br />
# iptables -D INPUT -p udp -j REJECT --reject-with icmp-port-unreach<br />
# iptables -A INPUT -p udp -m recent --set --name UDP-PORTSCAN -j REJECT --reject-with icmp-port-unreach<br />
<br />
===== Restore the Final Rule =====<br />
<br />
If either or both of the portscanning tricks above were used the final default rule is no longer the last rule in the INPUT chain. It needs to be the last rule otherwise it will intercept the trick port scanner rules you just added and they will never be used. Simply delete the rule (-D), then add it once again using append (-A) which will place it at the end of the chain.<br />
<br />
# iptables -D INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
# iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable<br />
<br />
=== Protection against other attacks ===<br />
<br />
See the [[Sysctl#TCP/IP stack hardening|TCP/IP stack hardening]] guide for relevant kernel parameters.<br />
<br />
==== Bruteforce attacks ====<br />
<br />
Unfortunately, bruteforce attacks on services accessible via an external IP address are common. One reason for this is that the attacks are easy to do with the many tools available. Fortunately, there are a number of ways to protect the services against them. One is the use of appropriate {{ic|iptables}} rules which activate and blacklist an IP after a set number of packets attempt to initiate a connection. Another is the use of specialised daemons that monitor the logfiles for failed attempts and blacklist accordingly. <br />
{{Warning| Using an IP blacklist will stop trivial attacks but it relies on an additional daemon and successful logging (the partition containing /var can become full, especially if an attacker is pounding on the server). Additionally, if the attacker knows your IP address, they can send packets with a spoofed source header and get you locked out of the server. [[SSH keys]] provide an elegant solution to the problem of brute forcing without these problems.}}<br />
Two packages that ban IPs after too many password failures are [[Fail2ban]] or, for {{ic|sshd}} in particular, [[Sshguard]]. These two applications update iptables rules to reject future connections from blacklisted IP addresses.<br />
<br />
The following rules give an example configuration to mitigate SSH bruteforce attacks using {{ic|iptables}}.<br />
<br />
# iptables -N IN_SSH<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 3 --seconds 10 -j DROP<br />
# iptables -A IN_SSH -m recent --name sshbf --rttl --rcheck --hitcount 4 --seconds 1800 -j DROP <br />
# iptables -A IN_SSH -m recent --name sshbf --set -j ACCEPT<br />
<br />
Most of the options should be self-explanatory, they allow for three connection packets in ten seconds. Further tries in that time will blacklist the IP. The next rule adds a quirk by allowing a total of four attempts in 30 minutes. This is done because some bruteforce attacks are actually performed slow and not in a burst of attempts. The rules employ a number of additional options. To read more about them, check the original reference for this example: [http://compilefailure.blogspot.com/2011/04/better-ssh-brute-force-prevention-with.html compilefailure.blogspot.com]<br />
<br />
Using the above rules, now ensure that:<br />
# iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -j IN_SSH<br />
is in an appropriate position in the iptables.rules file. <br />
<br />
This arrangement works for the IN_SSH rule if you followed this entire wiki so far:<br />
*<br />
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT<br />
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j IN_SSH<br />
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP<br />
*<br />
<br />
The above rules can, of course, be used to protect any service, though protecting the SSH daemon is probably the most often required one.<br />
<br />
{{Tip|For self-testing the rules after setup, the actual blacklist happening can slow the test making it difficult to fine-tune parameters. One can watch the incoming attempts via {{ic|cat /proc/net/xt_recent/sshbf}}. To unblock the own IP during testing, root is needed {{ic|# echo / > /proc/net/xt_recent/sshbf}}}}<br />
<br />
=== Saving the rules ===<br />
<br />
The ruleset is now finished and should be saved to your hard drive so that it can be loaded on every boot.<br />
<br />
The systemd unit file points to the location where the rule configuration will be saved:<br />
<br />
iptables=/etc/iptables/iptables.rules<br />
ip6tables=/etc/iptables/ip6tables.rules<br />
<br />
Save the rules with this command:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded on boot enabling the '''iptables''' [[daemon]].<br />
<br />
Check that the rules load correctly using:<br />
<br />
# systemctl start iptables.service && systemctl status iptables.service<br />
<br />
=== IPv6 ===<br />
<br />
If you do not use IPv6 (most ISPs do not support it), you should [[Disabling IPv6|disable it]].<br />
<br />
Otherwise, you should enable the firewall rules for IPv6. Just copy '''/etc/iptables/iptables.rules''' to '''/etc/iptables/ip6tables.rules''' and change IPs from v4 format to v6 format and change reject messages from <br />
--reject-with icmp-port-unreachable<br />
to<br />
--reject-with icmp6-port-unreachable<br />
etc.<br />
<br />
Please be aware that '''--reject-with icmp6-proto-unreachable''' does not exist for ICMPv6, so you may reject without any message. (Does anyone know what message would be correct? communication-prohibited? port-unreachable?).<br />
<br />
Since there is no kernel reverse path filter for IPv6, you may want to enable one in ip6tables with the folowing (The first rule is necessary to retain usually needed link local ICMPv6 multicasts):<br />
<br />
ip6tables -t raw -A PREROUTING -p icmpv6 -s fe80::/64 -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT<br />
ip6tables -t raw -A PREROUTING -j DROP<br />
<br />
Now you need to enable the '''ip6tables''' service using [[systemd]].<br />
<br />
== Setting up a NAT gateway ==<br />
<br />
This section of the guide deals with NAT gateways. It is assumed that you already read the [[#Firewall for a single machine|first part of the guide]] and set up the '''INPUT''', '''OUTPUT''', '''TCP''' and '''UDP''' chains like described above. All rules so far have been created in the '''filter''' table. In this section, we will also have to use the '''nat''' table.<br />
<br />
=== Setting up the filter table ===<br />
<br />
==== Creating necessary chains ====<br />
<br />
In our setup, we will use another two chains in the filter table, the '''fw-interfaces''' and '''fw-open''' chains. Create them with the commands<br />
<br />
# iptables -N fw-interfaces<br />
# iptables -N fw-open<br />
<br />
==== Setting up the FORWARD chain ====<br />
<br />
Setting up the '''FORWARD''' chain is similar to the '''INPUT''' chain in the first section.<br />
<br />
Now we set up a rule with the '''conntrack''' match, identical to the one in the '''INPUT''' chain:<br />
<br />
# iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT<br />
<br />
The next step is to enable forwarding for trusted interfaces and to make all packets pass the '''fw-open''' chain.<br />
<br />
# iptables -A FORWARD -j fw-interfaces <br />
# iptables -A FORWARD -j fw-open <br />
<br />
The remaining packets are denied with an '''ICMP''' message:<br />
<br />
# iptables -A FORWARD -j REJECT --reject-with icmp-host-unreach<br />
# iptables -P FORWARD DROP<br />
<br />
==== Setting up the fw-interfaces and fw-open chains ====<br />
<br />
The meaning of the '''fw-interfaces''' and '''fw-open''' chains is explained later, when we deal with the '''POSTROUTING''' and '''PREROUTING''' chains in the '''nat''' table, respectively.<br />
<br />
=== Setting up the nat table ===<br />
<br />
All over this section, we assume that the outgoing interface (the one with the public internet IP) is '''ppp0'''. Keep in mind that you have to change the name in all following rules if your outgoing interface has another name.<br />
<br />
==== Setting up the POSTROUTING chain ====<br />
<br />
Now, we have to define who is allowed to connect to the internet. Let's assume we have the subnet '''192.168.0.0/24''' (which means all addresses that are of the form 192.168.0.*) on '''eth0'''. We first need to accept the machines on this interface in the FORWARD table, that is why we created the '''fw-interfaces''' chain above:<br />
<br />
# iptables -A fw-interfaces -i eth0 -j ACCEPT<br />
<br />
Now, we have to alter all outgoing packets so that they have our public IP address as the source address, instead of the local LAN address. To do this, we use the '''MASQUERADE''' target:<br />
<br />
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE<br />
<br />
Do not forget the '''-o ppp0''' parameter above. If you omit it, your network will be screwed up.<br />
<br />
Let's assume we have another subnet, '''10.3.0.0/16''' (which means all addresses 10.3.*.*), on the interface '''eth1'''. We add the same rules as above again:<br />
<br />
# iptables -A fw-interfaces -i eth1 -j ACCEPT<br />
# iptables -t nat -A POSTROUTING -s 10.3.0.0/16 -o ppp0 -j MASQUERADE<br />
<br />
The last step is to enable IP Forwarding (if it is not already enabled):<br />
<br />
# echo 1 > /proc/sys/net/ipv4/ip_forward<br />
<br />
Then edit the relevant line in {{ic|/etc/sysctl.d/90-firewall.conf}} so it persists through reboot (see [[sysctl]] for details):<br />
<br />
net.ipv4.ip_forward = 1<br />
<br />
Machines from these subnets can now use your new NAT machine as their gateway. Note that you may want to set up a DNS and DHCP server like '''dnsmasq''' or a combination of '''bind''' and '''dhcpd''' to simplify network settings DNS resolution on the client machines. This is not the topic of this guide.<br />
<br />
==== Setting up the PREROUTING chain ====<br />
<br />
Sometimes, we want to change the address of an incoming packet from the gateway to a LAN machine. To do this, we use the '''fw-open''' chain defined above, as well as the '''PREROUTING''' chain in the '''nat''' table<br />
<br />
I will give two simple examples: First, we want to change all incoming SSH packets (port 22) to the ssh server in the machine '''192.168.0.5''':<br />
<br />
# iptables -A fw-open -d 192.168.0.5 -p tcp --dport 22 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 22 -j DNAT --to 192.168.0.5<br />
<br />
The second example will show you how to change packets to a different port than the incoming port. We want to change any incoming connection on port '''8000''' to our web server on '''192.168.0.6''', port '''80''':<br />
<br />
# iptables -A fw-open -d 192.168.0.6 -p tcp --dport 80 -j ACCEPT<br />
# iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 8000 -j DNAT --to 192.168.0.6:80<br />
<br />
The same setup also works with udp packets.<br />
<br />
=== Saving the rules ===<br />
<br />
Save the rules:<br />
<br />
# iptables-save > /etc/iptables/iptables.rules<br />
<br />
and make sure your rules are loaded when you boot enabling the '''iptables''' [[daemon]].<br />
<br />
== See Also ==<br />
<br />
*[[Internet sharing]]<br />
*[[Router]]<br />
*[[Firewalls]]<br />
*[[Uncomplicated Firewall]]<br />
*[http://www.webhostingtalk.com/showthread.php?t=456571 Methods to block SSH attacks]<br />
*[http://www.ducea.com/2006/06/28/using-iptables-to-block-brute-force-attacks/ Using iptables to block brute force attacks]<br />
*[http://linuxconfig.org/collection-of-basic-linux-firewall-iptables-rules 20 Iptables Examples For New SysAdmins]<br />
*[http://www.thegeekstuff.com/2011/06/iptables-rules-examples/ 25 Most Frequently Used Linux IPTables Rules Examples]</div>Branchhttps://wiki.archlinux.org/index.php?title=Router&diff=307725Router2014-03-31T04:06:56Z<p>Branch: /* Acquiring WAN IPv6 via DHCPv6-PD */ sysctl setting to allow dynamic IPv6 default route when dhcpcd is used for IA_PD</p>
<hr />
<div>[[Category:Networking]]<br />
[[Category:Security]]<br />
This article is a tutorial for turning a computer into an internet gateway/router. It focuses on ''security'', since the gateway is connected directly to the Internet. It should not run '''any''' services available to the outside world. Towards the LAN, it should only run gateway specific services. It should not run httpd, ftpd, samba, nfsd, etc. as those belong on a server in the LAN as they introduce security flaws.<br />
<br />
This article does not attempt to show how to set up a shared connection between 2 PCs using cross-over cables. For a simple internet sharing solution, see [[Internet sharing]].<br />
<br />
==Hardware Requirements==<br />
* At least 1 GB of hard drive space. The base install will take up around 500MB of space and if you want to use a caching web proxy, you will need to reserve space for the cache as well.<br />
* At least two physical network interfaces: a gateway connects two networks with each other. You will need to be able to connect those networks to the same physical computer. One interface must connect to the external network, while the other connects to the internal network.<br />
* A hub, switch or UTP cable: You need a way to connect the other computers to the gateway<br />
<br />
==Conventions==<br />
Conventions in this guide will be to use non-realistic interface names, to avoid confusion about which interface is which.<br />
<br />
* '''intern0''': the network card connected to the LAN. On an actual computer it will probably have the name enp2s0, enp1s1, etc.<br />
* '''extern1''': the network card connected to the external network (or WAN). It will probably have the name enp2s0, enp1s1, etc.<br />
<br />
==Installation==<br />
{{Note | For a full installation guide, see the [[Installation guide]].}}<br />
<br />
A fresh install of Arch Linux is the easiest to start from, as no configuration changes have been made and there is a minimal amount of packages installed. This is helpful when attempting to reduce security risk.<br />
<br />
===Partitioning===<br />
<br />
For security purposes, {{ic|/var}}, {{ic|/tmp}} and {{ic|/home}} should be separate from the {{ic|/}} partition. This prevents disk space from being completely used up by log files, daemons or the unprivileged user. It also allows different mount options for those partitions. If you have already partitioned your drive, the [http://gparted.sourceforge.net/ gparted livecd] can be used to resize, move, or create new partitions.<br />
<br />
Your home and root partitions can be much smaller than a regular install since this is not a desktop machine. {{ic|/var}} should be the largest partition—it is where databases, logs and long-term caches are stored. If you have a lot of RAM, mounting {{ic|/tmp}} as {{ic|tmpfs}} is a good idea, so making a disk partition for it during the initial install is unnecessary. Note that {{ic|/tmp}} is mounted as {{ic|tmpfs}} by default in Arch.<br />
<br />
===Post-Installation===<br />
After creation of non-root account you are recommended to install [[sudo]] and [[sudo#Disable root login|disable root login]].<br />
<br />
==Network interface configuration==<br />
<br />
===Persistent naming and Interface renaming===<br />
Systemd automatically chooses unique interface names for all your interfaces. These are persistent and will not change when you reboot. If you would like to rename interface to user friendlier names read [[Network configuration#Device_names]].<br />
<br />
===IP configuration===<br />
Now you will need to configure the network interfaces. The best way to do so is using [[netctl]] profiles. You will need to create two profiles.<br />
{{Note|If you will be connecting to the Internet only via PPPoE (you have one WAN port) you '''do not need''' to setup or enable the extern0-profile. See below for more information on configuring PPPoE.}}<br />
* {{ic|/etc/netctl/extern0-profile}}<br />
Description='Public Interface.'<br />
Interface=extern0<br />
Connection=ethernet<br />
IP='dhcp'<br />
<br />
* {{ic|/etc/netctl/intern0-profile}}<br />
Description='Private Interface'<br />
Interface=intern0<br />
Connection=ethernet<br />
IP='static'<br />
Address=('10.0.0.1/24')<br />
<br />
{{Note|The example configuration above assumes a full subnet. If you are building the gateway for a small amount of people, you will want to change the CIDR suffix to accommodate a smaller range. For example /27 will give you 10.0.0.1 to 10.0.0.30. You can find many CIDR calculators online.}}<br />
<br />
Next up is to set up the interfaces with netctl.<br />
# netctl enable extern0-profile<br />
# netctl enable intern0-profile<br />
<br />
==ADSL connection/PPPoE==<br />
Using rp-pppoe, we can connect an ADSL modem to the extern1 of the firewall and have Arch manage the connection. Make sure you put the modem in ''bridged'' mode though (either half-bridge or RFC1483), otherwise the modem will act as a router too.<br />
# pacman -S rp-pppoe<br />
<br />
It should be noted that if you use only PPPoE to connect to the internet (ie. you do not have other WAN port, except for the one that connects to your modem) you do not need to set up the {{ic|extern0-profile}} as the external pseudo-interface will be ppp0.<br />
<br />
===PPPoE configuration===<br />
You can use netctl to setup the pppoe connection. To get started<br />
# cp /etc/netctl/examples/pppoe /etc/netctl/<br />
and start editing. For the interface configuration choose the interface that connects to the modem. If you only connect to the internet through PPPoE this will probably be {{ic|extern0}}. Fill in the rest of the fields with your ISP information. See the pppoe section in netctl.profile man page for more information on the fields.<br />
<br />
==DNS and DHCP==<br />
We will use [[dnsmasq]], a DNS and DHCP daemon for the LAN. It was specifically designed for small sites. To get it, [[Pacman | install]] {{Pkg|dnsmasq}} from the [[official repositories]].<br />
<br />
Dnsmasq needs to be configured to be a DHCP server. To do this:<br />
<br />
Edit {{ic|/etc/dnsmasq.conf}}:<br />
<br />
interface=intern0 # make dnsmasq listen for requests only on intern0 (our LAN)<br />
expand-hosts # add a domain to simple hostnames in /etc/hosts<br />
domain=foo.bar # allow fully qualified domain names for DHCP hosts (needed when<br />
# "expand-hosts" is used)<br />
dhcp-range=10.0.0.2,10.0.0.255,255.255.255.0,1h # defines a DHCP-range for the LAN: <br />
# from 10.0.0.2 to .255 with a subnet mask of 255.255.255.0 and a<br />
# DHCP lease of 1 hour (change to your own preferences)<br />
<br />
Somewhere below, you will notice you can also add "static" DHCP leases, i.e. assign an IP-address to the MAC-address of a computer on the LAN. This way, whenever the computer requests a new lease, it will get the same IP. That is very useful for network servers with a DNS record. You can also deny certain MAC's from obtaining an IP.<br />
<br />
Now start dnsmasq:<br />
# systemctl start dnsmasq.service<br />
<br />
==Connection sharing==<br />
<br />
Time to tie the two network interfaces to each other.<br />
===iptables===<br />
[[Simple stateful firewall]] documents the setup of an [[iptables]] firewall and NAT.<br />
<br />
Make sure you added the firewall exceptions for DHCP and Domain, if you want to use Dnsmasq:<br />
<br />
* Insert Rules:<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 67 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p udp -m udp --dport 53 -j ACCEPT<br />
# iptables -t filter -I INPUT -i intern0 -p tcp -m tcp --dport 53 -j ACCEPT<br />
<br />
<br />
===Shorewall===<br />
Shorewall, an iptables frontend, can be used as an easier alternative. See [[Shorewall]] for detailed configuration.<br />
<br />
==IPv6==<br />
<br />
{{Merge|IPv6|Merge into the main article, the topic is not specific to ''router configuration''. The wording should be probably changed along the way.}}<br />
<br />
''Useful reading: [[IPv6]] and the [https://en.wikipedia.org/wiki/IPv6 Wikipedia IPv6 entry].''<br />
<br />
You can use your router in IPv6 mode even if you do not have an IPv6 address from your ISP. Unless you disable IPv6 all interfaces should have been assigned a unique {{ic|fe80::/10}} address.<br />
<br />
For internal networking the block {{ic|fc00::/7}} has been reserved. These addresses are guaranteed to be unique and non-routable from the open internet. Addresses that belong to the {{ic|fc00::/7}} block are called [http://en.wikipedia.org/wiki/Unique_local_address Unique Local Addresses]. To get started [http://www.simpledns.com/private-ipv6.aspx generate a ULA /64 block] to use in your network. For this example we will use {{ic|fd00:aaaa:bbbb:cccc::/64}}. Firstly we must assign a static IPv6 on the internal interface. Modify the {{ic|intern0-profile}} we created above to include the following line<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::1/64 dev intern0')<br />
This will add the ULA to the internal interface. As far as the router goes, this is all you need to configure.<br />
<br />
===Router Advertisement and Stateless Autoconfiguration (SLAAC)===<br />
<br />
To properly hand out IPv6s to the network clients we will need to use an advertising daemon. The standard tool for this job is {{Pkg|radvd}} and is available in [[official repositories]]. Configuration of radvd is fairly simple. Edit {{ic|/etc/radvd.conf}} to include<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
The above configuration will tell clients to autoconfigure themselves using addresses from the specified /64 block. Addresses on the clients are uniquely generated using the MAC address of the connected interface and are optionally mangled for security reasons if [[IPv6#Privacy_Extensions|privacy extensions]] are enabled (which is recommended to do). On the client side you need to enable {{ic|1=IP6=stateless}} in your active netctl profile. If you want a static IP as well add<br />
IPCustom=('-6 addr add fd00:aaaa:bbbb:cccc::2/64 dev eth0')<br />
<br />
Don't forget to enable radvd.service<br />
<br />
====Firewall tweaks====<br />
<br />
Stateless autoconfiguration works on the condition that IPv6 icmp packets are allowed throughout the network. So some firewall tweaks are required on both ends of the network for it to work properly. On the '''client side''' all you need to do is allow the {{ic|ipv6-icmp}} protocol on the INPUT chain. If you are using [[Simple stateful firewall]] you only need to add<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
<br />
You can limit it to internal network using {{ic|-s fd00:aaaa:bbbb:cccc::/64}} and/or {{ic|-s fe80::/10}} if you feel it is a security threat. Additionally you must add the same rules to your router firewall but extending it to the OUTPUT and FORWARD chains as well.<br />
<br />
-A INPUT -p ipv6-icmp -j ACCEPT<br />
-A OUTPUT -p ipv6-icmp -j ACCEPT<br />
-A FORWARD -p ipv6-icmp -j ACCEPT<br />
<br />
Again, you can limit it to the internal network for the INPUT chain.<br />
<br />
{{Expansion|More information on IPv6 firewalls required}}<br />
{{Expansion|Additional info on running DHCPv6 server instead of SLAAC}}<br />
<br />
===Global Unicast Addresses===<br />
<br />
====Static WAN IPv6====<br />
<br />
If your ISP or WAN network can access the IPv6 Internet you can assign global link addresses to your router and propagate them through SLAAC to your internal network. If you can use a Static IPv6 all you must do is add it to your external profile and enable it the advertisement of the global unicast block in {{ic|radvd.conf}}.<br />
<br />
In {{ic|/etc/netctl/extern0-profile}} simply add the IPv6 and the IPv6 prefix (usually /64) you have been provided<br />
<br />
IPCustom=('-6 addr add 2002:1:2:3:4:5:6:7/64 dev extern0')<br />
<br />
and edit {{ic|/etc/radvd.conf}} to include the new advertisement block.<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix fd00:aaaa:bbbb:cccc::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
prefix 2002:1:2:3::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
};<br />
};<br />
<br />
In that way your internal network clients will also get a Global IPv6 address. This IP is routable from the open internet, so adjust your firewalls. Please note that global and local IPv6s can co-exist on the same interface without further configuration.<br />
<br />
====Acquiring WAN IPv6 via DHCPv6-PD====<br />
<br />
If your ISP handles out IPv6s using [[wikipedia:Prefix_delegation|DHCPv6-PD]] you will need to use a DHCPv6 client to get the IP from your ISP. Common such programs are {{AUR|dibbler}}, {{AUR|wide-dhcpv6}} and {{Pkg|dhcpcd}}. ISC's {{Pkg|dhclient}} should also work, but documentation on prefix delegation is scarce.<br />
<br />
For '''dibbler''' edit {{ic|/etc/dibbler/client.conf}}<br />
<br />
log-mode short<br />
log-level 7<br />
iface "extern0" {<br />
ia<br />
pd<br />
}<br />
<br />
{{Tip|Read manpage '''{{ic|dibbler-client(8)}}''' for more information.}}<br />
<br />
For '''wide-dhcpv6''' edit {{ic|/etc/wide-dhcpv6/dhcp6c.conf}}<br />
<br />
interface extern0 {<br />
send ia-pd 0;<br />
};<br />
<br />
id-assoc pd 0 {<br />
prefix-interface intern0 {<br />
sla-id 1;<br />
sla-len 8;<br />
};<br />
};<br />
<br />
To enable/start wide-dhcpv6 client use the command<br />
# systemctl enable/start dhcp6c@extern0.service<br />
<br />
{{Tip|Read manpages '''{{ic|dhcp6c(8)}}''' and '''{{ic|dhcp6c.conf(5)}}''' for more information.}}<br />
<br />
For '''dhcpcd''' edit {{ic|/etc/dhcpcd.conf}}. You might already be using dhcpcd for IPv4 so just update your existing configuration. If you would like to use it for IPv6 only uncomment the third line.<br />
<br />
duid<br />
noipv6rs<br />
#ipv6only<br />
interface extern0<br />
ia_pd 1 intern0<br />
<br />
This configuration will ask for a prefix from WAN (interface {{ic|extern0}}) and delegate it to the internal interface ({{ic|intern0}}).<br />
<br />
Because this configuration will neither solicit nor accept router advertisements no default route will be set. The kernel IPv6 stack can be allowed to set a dynamic default route with:<br />
<br />
sysctl -w net.ipv6.conf.extern0.accept_ra=2<br />
<br />
Or to have it persist after reboot:<br />
<br />
echo net.ipv6.conf.extern0.accept_ra = 2 > /etc/sysctl.d/80-ipv6dynroute.conf<br />
<br />
{{Tip|Also read: manpages '''{{ic|dhcpcd(8)}}''' and '''{{ic|dhcpcd.conf(5)}}'''.}}<br />
<br />
Because the IPv6 prefix is now dynamic, we need to change radvd to advertize any subnet instead of specific ones. With this configuration radvd will pick any /64 prefix available on the internal interface and propagate SLAAC IPv6s to the clients. Simply change {{ic|/etc/radvd.conf}} to<br />
<br />
interface intern0 {<br />
AdvSendAdvert on;<br />
MinRtrAdvInterval 3;<br />
MaxRtrAdvInterval 10;<br />
prefix ::/64 {<br />
AdvOnLink on;<br />
AdvAutonomous on;<br />
AdvRouterAddr on;<br />
DeprecatePrefix on;<br />
};<br />
};<br />
<br />
====PPPoE and IPv6====<br />
If your ISP provides IPv6 via PPPoE you can enable it in your pppoe netctl profile. Just add this to pppoe netctl profile<br />
<br />
PPPoEIP6=yes<br />
<br />
and restart it. Also you must change any {{ic|extern0}} references to the configuration files above to {{ic|ppp0}} instead since IPv6 is assigned to ppp pseudo-interface instead of a real ethernet interface. Please note, that depending on your modem IPv6 might not be available through half-bridge so switch to full RFC1483 bridging instead.<br />
<br />
{{Warning|dhclient does not support DHCP6-PD via PPP}}<br />
<br />
==Cleanup==<br />
<br />
Now that the installation has been performed, it is necessary to remove as many packages as possible. Since we are making a gateway, keeping unneeded packages only "bloats" the system, and increases the number of security risks.<br />
<br />
First, check for obsolete/deprecated packages (likely after a fresh install and massive series of updates):<br />
<br />
$ pacman -Qm<br />
<br />
Review the list of explicitly installed packages that are not dependencies and remove any that are unneeded. Having only needed packages installed is an important security consideration.<br />
<br />
$ pacman -Qet<br />
<br />
Completely remove the packages you do not need along with their configuration files and dependencies:<br />
<br />
# pacman -Rsn package1 package2 package3<br />
<br />
== Logrotate ==<br />
<br />
You should review the [[logrotate]] configuration to make sure the box is not brought down by lack of diskspace due to logging.<br />
<br />
Logrotate is installed by default, so you will not have to install it.<br />
<br />
==Optional additions==<br />
<br />
===UPnP===<br />
The above configuration of shorewall does not include [[Wikipedia:UPnP|UPnP]] support. Use of UPnP is discouraged as it may make the gateway vulnerable to attacks from within the LAN. However, some applications require this to function correctly.<br />
<br />
To enable UPnP on your router, you need to install an UPnP Internet gateway daemon (IGD). To get it, install {{Pkg|miniupnpd}} from the [[official repositories]].<br />
<br />
Read the [http://www.shorewall.net/UPnP.html Shorewall guide on UPnP] for more information<br />
<br />
===Remote administration===<br />
<br />
[[SSH|OpenSSH]] can be used to administer your router remotely. This is useful for running it "headless" (no monitor or input devices).<br />
<br />
=== Caching web proxy ===<br />
<br />
See [[Squid]] or [[Polipo]] for the setup of a web proxy to speed up browsing and/or adding an extra layer of security.<br />
<br />
=== Time server ===<br />
To use the router as a time server, see [[Network Time Protocol]].<br />
<br />
Then, configure shorewall or iptables to allow NTP traffic in and out.<br />
<br />
=== Content filtering ===<br />
<br />
Install and configure [[DansGuardian]] or [[Privoxy]] if you need a content filtering solution.<br />
<br />
=== Traffic shaping ===<br />
<br />
Traffic shaping is very useful, especially when you are not the only one on the LAN. The idea is to assign a priority to different types of traffic. Interactive traffic (ssh, online gaming) probably needs the highest priority, while P2P traffic can do with the lowest. Then there is everything in between.<br />
<br />
==== Traffic shaping with shorewall ====<br />
<br />
Read [http://www.shorewall.net/traffic_shaping.htm Shorewall's Traffic Shaping/Control] guide.<br />
<br />
Here is my config as an example:<br />
* /etc/shorewall/tcdevices : here is where you define the interface you want to have shaped and its rates. I have got a ADSL connection with a 4MBit down/256KBit up profile.<br />
ppp0 4mbit 256kbit <br />
* /etc/shorewall/tcclasses : here you define the minimum (rate) and maximum (ceil) throughput per class. You will assign each one to a type of traffic to shape.<br />
# interactive traffic (ssh)<br />
ppp0 1 full full 0<br />
# online gaming<br />
ppp0 2 full/2 full 5<br />
# http<br />
ppp0 3 full/4 full 10<br />
# rest<br />
ppp0 4 full/6 full 15 default<br />
* /etc/shorewall/tcrules : this file contains the types of traffic and the class it belongs to.<br />
1 0.0.0.0/0 0.0.0.0/0 tcp ssh<br />
2 0.0.0.0/0 0.0.0.0/0 udp 27000:28000<br />
3 0.0.0.0/0 0.0.0.0/0 tcp http<br />
3 0.0.0.0/0 0.0.0.0/0 tcp https<br />
I have split it up my traffic in 4 groups: <br />
# interactive traffic or ssh: although it takes up almost no bandwidth, it is very annoying if it lags due to leechers on the LAN. This get the highest priority.<br />
# online gaming: needless to say you ca not play when your ping sucks. ;)<br />
# webtraffic: can be a bit slower<br />
# everything else: every sort of download, they are the cause of the lag anyway.<br />
<br />
===Intrusion detection and prevention with snort===<br />
<br />
See [[Snort]].<br />
<br />
==See also==<br />
*[[Simple stateful firewall]]<br />
*[[Internet sharing]]</div>Branch