.\" Copyright (c) 2023 Joost van Baal-Ilić .TH "uruk" 8 "9 окт 2023" "uruk 20231009" "SYSTEM ADMINISTRATION " .po 2m .de ZI .\" Zoem Indent/Itemize macro I. .br 'in +\\$1 .nr xa 0 .nr xa -\\$1 .nr xb \\$1 .nr xb -\\w'\\$2' \h'|\\n(xau'\\$2\h'\\n(xbu'\\ .. .de ZJ .br .\" Zoem Indent/Itemize macro II. 'in +\\$1 'in +\\$2 .nr xa 0 .nr xa -\\$2 .nr xa -\\w'\\$3' .nr xb \\$2 \h'|\\n(xau'\\$3\h'\\n(xbu'\\ .. .if n .ll -2m .am SH .ie n .in 4m .el .in 8m .. .SH NAME uruk \- wrapper for Linux iptables, for managing firewall rules .SH SYNOPSIS \fBuruk\fP .SH DESCRIPTION \fBuruk\fP loads an \fIrc\fP file (see \fBuruk-rc(5)\fP) which defines network service access policy, and invokes \fBiptables(8)\fP to set up firewall rules implementing this policy\&. By default the file \fC/etc/uruk/rc\fP is used; one can overrule this by specifying another file in the URUK_CONFIG environment variable\&. Under some circumstances, it\&'s useful to use another command for iptables; this can be achieved by setting the URUK_IPTABLES (and/or URUK_IP6TABLES) environment variables\&. See \fBuruk-rc(5)\fP for details\&. .SH QUICK SETUP GUIDE Uruk will \fInot\fP "just work" out of the box\&. It needs manual configuration\&. For those of you who don\&'t like reading lots of documentation: .di ZV .in 0 .nf \fC # cp /usr/share/doc/uruk/examples/rc \e /etc/uruk/rc # vi /etc/uruk/rc # urukctl start .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .SH GETTING STARTED Once the \fBuruk\fP script is installed, you want to go use it, of course\&. We\&'ll give a detailed description of what to do here\&. First, create an \fIrc\fP file\&. See \fBuruk-rc(5)\fP for info on how to do this\&. Once this file is created and installed (this script looks in \fC/etc/uruk/rc\fP by default), you\&'re ready to run \fBuruk\fP\&. You might want to test your \fIrc\fP file by running \fBuruk\fP in debug mode, see \fBuruk-rc(5)\fP\&. There are at least 3 ways to load your \fIrc\fP file\&. We\&'ll first describe a low level one: using vanilla iptables\&. \fBVanilla iptables\fP .br After editing \fIrc\fP, load your rules like this\&. First flush your current rules: .di ZV .in 0 .nf \fC # iptables -F # ip6tables -F .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR Then enable your \fIrc\fP rules .di ZV .in 0 .nf \fC # uruk .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR \&. Inspect the rules by doing: .di ZV .in 0 .nf \fC # iptables -L # ip6tables -L .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR \&. If you want to make these changes survive a reboot, use the init script as shipped with this package\&. If you\&'d rather write your own init script, the \fBiptables-restore(8)\fP and \fBiptables-save(8)\fP commands from the iptables package might be helpful\&. \fBUsing the Uruk init script\fP .br Assumed is the Uruk init script is installed as explained in the README file\&. Optionally, install \fC/etc/default/uruk\fP (or \fC/etc/sysconfig/uruk\fP) and tweak it\&. An example file is in \fC/usr/share/doc/uruk/examples/default\fP (You might like to enable support for \fBuruk-save\fP\&.) Now activate uruk by doing: .di ZV .in 0 .nf \fC # urukctl start .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR Now your pre-uruk iptables rules (if any) are saved as the "inactive" ruleset\&. While executing \fCurukctl start\fP, your box is open during a short while\&. If you don\&'t like this, read below about \fBuruk-save\fP\&. When rebooting, everything will be fine: \fC/etc/init\&.d/uruk\fP stores state in \fC/var/lib/uruk/iptables\fP, using iptables-save(8), which comes with Linux iptables\&. \fBUsing Debian ifupdown\fP .br In case you have just one network interface which should get protected, you could use \fBinterfaces(5)\fP from the Debian ifupdown package instead of the init script\&. Suppose you\&'d like to protect \fCppp0\fP, and would like not to interfere with traffic on eth0: your other network interface\&. First write an \fIrc\fP file\&. Be sure it features .di ZV .in 0 .nf \fC interfaces_unprotect="lo eth0" .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR Then run: .di ZV .in 0 .nf \fC # mkdir -p /var/lib/uruk/iptables # iptables -F # iptables-save -c > /var/lib/uruk/iptables/down # uruk # iptables-save -c > /var/lib/uruk/iptables/up .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR Add .di ZV .in 0 .nf \fC pre-up iptables-restore < /var/lib/uruk/iptables/up post-down iptables-restore < /var/lib/uruk/iptables/down .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR to your interfaces stanza, in your \fC/etc/network/interfaces\fP \&. Similar tricks might be possible on GNU/Linux systems from other distributions\&. The author is interested\&. .SH LOADING A NEW \fIrc\fP FILE Need to change your rules? \fBUsing the Uruk init script\fP .br Do .di ZV .in 0 .nf \fC # vi /etc/uruk/rc # urukctl force-reload .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR While executing \fCurukctl force-reload\fP, your box is open during a short while\&. If you don\&'t like this, read below about \fBuruk-save\fP\&. .SH THE GORY DETAILS: uruk INTERNALS The \fBuruk\fP script works like (and looks like) the list of statements below\&. Of course, take a look at \fC/sbin/uruk\fP for the final word on the workings\&. .ZI 2m "1" \& .br \fIrc\fP is sourced as a shell script .in -2m .ZI 2m "2" \& .br Traffic on $interfaces_unprotect (just lo per default) is trusted: .di ZV .in 0 .nf \fC $iptables -A INPUT -i $iface -j ACCEPT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "3" \& .br $rc_a is sourced as a shell script, or, in case $rc_a is a directory, all files matching $rc_a/*\&.rc are sourced as shell scripts .in -2m .ZI 2m "4" \& .br ESTABLISHED and RELATED packets are ACCEPT-ed: .di ZV .in 0 .nf \fC $iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED \e -j ACCEPT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "5" \& .br $rc_b is sourced .in -2m .ZI 2m "6" \& .br $interfaces gets protected against spoofing: we don\&'t allow anyone to spoof non-routeable addresses\&. We block outgoing packets that don\&'t have our address as source: they are either spoofed or something is misconfigured (NAT disabled, for instance)\&. We want to be nice and don\&'t send out garbage\&. .di ZV .in 0 .nf \fC $iptables -A INPUT -i $iface --source $no_route_ip \e -j DROP .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR We drop all incoming packets which don\&'t have us as destination: .di ZV .in 0 .nf \fC $iptables -A OUTPUT -o $iface --source ! "$ip" \e -j DROP .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR And we always allow outgoing connections: .di ZV .in 0 .nf \fC $iptables -A OUTPUT -m conntrack --ctstate NEW -o $iface \e -j ACCEPT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "7" \& .br $rc_c is sourced .in -2m .ZI 2m "8" \& .br Allow traffic to offered services, from trusted sources: .di ZV .in 0 .nf \fC $iptables -A INPUT -m conntrack --ctstate NEW \e -i $iface --protocol $proto --source "$source" \e --destination "$ip" --destination-port "$port" \e -j ACCEPT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "9" \& .br $rc_d is sourced .in -2m .ZI 2m "10" \& .br Don\&'t answer broadcast and multicast packets: .di ZV .in 0 .nf \fC $iptables -A INPUT -i $iface --destination "$bcast" \e -j DROP .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "11" \& .br $rc_f is sourced .in -2m .ZI 2m "12" \& .br Explicitly allow a subset of the ICMP types\&. (We disallow all other traffic later\&.) .di ZV .in 0 .nf \fC $iptables -A INPUT --protocol icmp --icmp-type $type \e -j ACCEPT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "13" \& .br $rc_g is sourced .in -2m .ZI 2m "14" \& .br Log packets (which make it till here) .di ZV .in 0 .nf \fC $iptables -A INPUT -j LOG --log-level debug \e --log-prefix \&'iptables: \&' .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "15" \& .br $rc_h is sourced .in -2m .ZI 2m "16" \& .br Reject all other packets .di ZV .in 0 .nf \fC $iptables -A INPUT -j REJECT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR .in -2m .ZI 2m "17" \& .br $rc_i is sourced .in -2m .SH USING uruk-save AS THE INITSCRIPT BACKEND By default, \fBuruk-save\fP is not used by the uruk init script\&. You might want to use it, though\&. The \fBuruk-save\fP script is faster and when using \fBuruk-save\fP, your box won\&'t be open while loading new rules\&. But beware: \fBuruk-save\fP is not as robust as using \fBuruk\fP itself\&. The script \fBurukctl\fP (and thus the uruk init script) will use \fBuruk-save\fP only if asked to do so in \fC/etc/default/uruk\fP (or \fC/etc/sysconfig/uruk\fP)\&. If this file features .di ZV .in 0 .nf \fC enable_uruk_save=true .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR \fBuruk-save\fP is used whenever appropriate\&. See \fBuruk-save(8)\fP for more details\&. .SH DEFAULT POLICY By default, \fBuruk\fP drops packets which have unknown RFC 1918 private network addresses in their source or destination\&. It rejects packets with source nor destination for one of our IPs\&. Packets belonging to locally initiated sessions are allowed: we match state; the local host can act as a client for any remote service\&. By default, \fBuruk\fP drops all ICMP packets (except those for interfaces in $interfaces_unprotect) with type other than .ZI 2m "\(bu" \& .br address-mask-reply .in -2m .ZI 2m "\(bu" \& .br address-mask-request .in -2m .ZI 2m "\(bu" \& .br destination-unreachable (this is a catch-all for a lot of types) .in -2m .ZI 2m "\(bu" \& .br echo-request .in -2m .ZI 2m "\(bu" \& .br echo-reply .in -2m .ZI 2m "\(bu" \& .br parameter-problem (catch-all for ip-header-bad and required-option-missing) .in -2m .ZI 2m "\(bu" \& .br timestamp-reply .in -2m .ZI 2m "\(bu" \& .br timestamp-request .in -2m .ZI 2m "\(bu" \& .br ttl-zero-during-transit .in -2m .ZI 2m "\(bu" \& .br ttl-zero-during-reassembly .in -2m By default, the FORWARD chain is left untouched, so has policy ACCEPT\&. (This won\&'t do much harm, since packet forwarding is disabled by default in the Linux kernel\&. However, if you don\&'t mind being paranoid, you might want to add a .di ZV .in 0 .nf \fC iptables --policy FORWARD REJECT .fi \fR .in .di .ne \n(dnu .nf \fC .ZV .fi \fR to your $rc_a uruk hook\&. See \fBuruk-rc(5)\fP\&.) By default, \fBuruk\fP logs all UDP and TCP packets which are blocked by the user defined policies\&. Loglevel is debug, logprefix is "iptables:"\&. See also the notes on \fIloglevel\fP in \fBuruk-rc(5)\fP\&. Blocked TCP packets are answered with a tcp-reset\&. .SH WARNING In order to keep the \fBuruk\fP script small and simple, the script does very little error handling\&. It does not check the contents of the \fIrc\fP file in any way before executing it\&. When your \fIrc\fP file contains bogus stuff, \fBuruk\fP will very likely behave in unexpected ways\&. Caveat emptor\&. .SH ENVIRONMENT You can override some defaults in the shell before executing the uruk script\&. \fBuruk\fP honors the following variables: .ZI 2m "\(bu" \& .br "URUK_CONFIG" Full pathname of \fIrc\fP file; \fC/etc/uruk/rc\fP by default\&. .in -2m .ZI 2m "\(bu" \& .br "URUK_IPTABLES" Full pathname of iptables executable\&. \fC/sbin/iptables\fP by default\&. Overrides \fIiptables\fP\&. .in -2m .ZI 2m "\(bu" \& .br "URUK_IP6TABLES" Full pathname of ip6tables executable, for IPv6 support\&. Overrides \fIip6tables\fP\&. .in -2m .ZI 2m "\(bu" \& .br "URUK_INTERFACES_UNPROTECT" Default list of unprotected interfaces\&. Overrides \fIinterfaces_unprotect\fP\&. The default default is \fClo\fP\&. .in -2m .SH SEE ALSO \fBuruk-rc(5)\fP, \fBuruk-save(8)\fP\&. The Uruk homepage is at http://mdcc\&.cx/uruk/ \&. \fBiptables(8)\fP, \fBiptables-save(8)\fP, \fBiptables-restore(8)\fP, \fBip6tables(8)\fP, \fBip6tables-save(8)\fP, \fBip6tables-restore(8)\fP, http://www\&.netfilter\&.org/ \fBinterfaces(5)\fP, http://packages\&.debian\&.org/ifupdown\&. .SH COPYRIGHT Copyright (C) 2003 Stichting LogReport Foundation logreport@logreport\&.org; Copyright (C) 2003, 2004 Tilburg University http://www\&.uvt\&.nl/; Copyright (C) 2003-2013 Joost van Baal-Ilić This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version\&. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE\&. See the GNU General Public License for more details\&. You should have received a copy of the GNU General Public License along with this program\&. If not, see http://www\&.gnu\&.org/licenses/\&. .SH AUTHOR Joost van Baal-Ilić