summaryrefslogtreecommitdiff
path: root/firewall
blob: 1117ee5870e49446f9230bdd46c16a6a16cee7d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#!/bin/bash
#
# Iptables Setup and Initialization Script
# Version 1.0
#
# Written by Michael Crute (mcrute@gmail.com)
# for SoftGroup Interactive on July 10, 2006
# Last updated: same
#

if [ $UID != 0 ]; then
    echo "You are not root. Goodbye."
    exit 1
fi

IPT='/sbin/iptables'

GREEN='\033[0;32m'
WHITE='\033[0m'
RED='\033[0;31m'

ALLOW_PING=0
FUNNY_BUSINESS=0

function do_log 
{
    timestamp=`date +"[%Y-%m-%d %H:%M:%S]"`
    if [ $2 == 0 ]; then
        echo -e "$timestamp $1: [$GREEN OK $WHITE]"
    else
        echo -e "$timestamp $1: [$RED FAILED $WHITE]"
    fi
}

function flush_all 
{
    # Flush all existing chains and erase personal chains
    CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
    for i in $CHAINS; do
        $IPT -t $i -F
        $IPT -t $i -X
        do_log "Flushing chain $i" $? 
    done

    # Flush the conntrack database if we can
    if [ `which conntrack > /dev/null 2>&1` ]; then
        conntrack -F
        do_log "Flushing conntrack" $?
    fi

    $IPT -P INPUT ACCEPT
    do_log "All chains flushed" $?
}

function block_shenanigans
{
    iptables -A INPUT -f -j DROP
    do_log "Blocking packet fragments" $?
    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
    do_log "Blocking null packets" $?
    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
    do_log "Blocking christmas-tree packets" $?
}

function set_ping
{
    policy="ACCEPT"
    [[ $1 == 0 ]] && policy="DROP"

    $IPT -A INPUT -p icmp --icmp-type 8 -j $policy
    do_log "$policy pings" $?
}

function block_port
{
    $IPT -A INPUT -p $1 -m state --state NEW -m $1 --dport $2 -j DROP
    $IPT -A OUTPUT -p $1 -m state --state NEW -m $1 --dport $2 -j DROP
    do_log "Blocking $1 port $2" $?
}

function load_policy
{
    policy=`cat /etc/firewall/profile 2>/dev/null || echo 'default'`
    [[ ! -z "$1" ]] && policy=$1
    LOADFILE="/etc/firewall/iptables-$policy"

    if [ -r $LOADFILE ]; then
        source $LOADFILE
        flush_all
        do_log "Loading ruleset $LOADFILE" $?
    else
        do_log "Could not load a ruleset" 1
        exit 1
    fi
}

function filter_host
{
    $IPT -I INPUT -s $2 -j $1
    do_log "$1 host $2" $?
}

function filter_port 
{
    $IPT -A INPUT -p $2 -m state --state NEW -m $2 --dport $1 -j $3
    do_log "$3 $2 port $1" $?
}

function add_exception
{
    ip=`echo $1 | cut -d' ' -f1`
    prot=`echo $1 | cut -d' ' -f2`
    port=`echo $1 | cut -d' ' -f3`

    $IPT -A INPUT -p $prot -m state --state NEW -s $ip -m $prot --dport $port -j ACCEPT

    do_log "Allowing $ip for $prot $port" $?
}

function set_defaults
{
    $IPT -A INPUT -s 127.0.0.1 -j ACCEPT
    $IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPT -P INPUT DROP
    $IPT -P FORWARD DROP
    $IPT -P OUTPUT ACCEPT 
}

# Lockdown is the most strict policy that only passes
# ssh traffic. This is good for new servers and emergencies
function lockdown
{
    flush_all

    $IPT -P INPUT DROP
    $IPT -P FORWARD DROP
    $IPT -P OUTPUT DROP
    do_log "All chains set to drop" $?

    $IPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    $IPT -A OUTPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
    do_log "Allowing ssh only" $?

    do_log "Firewall locked down" $?
}

function build_firewall
{
    load_policy $1
    [[ $FUNNY_BUSINESS == 0 ]] && block_shenanigans
    set_defaults
    set_ping $ALLOW_PING
    
    # Set exceptions
    for idx in $(seq ${#RULES[@]}); do
        item=${RULES[$idx]}
        add_exception $item
    done;

    # Allow or deny hosts
    for host in $HOSTS_DENY; do
        filter_host "DROP" $host
    done
    for host in $HOSTS_ALLOW; do
        filter_host "ALLOW" $host
    done
    
    # Allow or deny tcp ports
    for port in $TCP_DENY; do
        block_port "tcp" $port
    done
    for port in $TCP_ALLOW; do
        filter_port $port "tcp" "ACCEPT"
    done

    # Allow or deny udp ports
    for port in $UDP_DENY; do
        block_port "udp" $port
    done
    for i in $UDP_ALLOW; do
        filter_port $port "udp" "ACCEPT"
    done
}

if [[ $1 == "--flush" ]]; then
    flush_all
    exit 0
elif [[ $1 == "--lockdown" ]]; then
    lockdown
    exit 0
else
    build_firewall $1
    do_log "Firewall started" $?
fi