summaryrefslogtreecommitdiffstats
path: root/ferm/ferm.conf
blob: 6b3003958d63d60c5dc97485ead8321937df5fc4 (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
197
198
199
200
201
202
# -*- shell-script -*-
#
#  Configuration file for ferm(1).
#

# host
@def $IP_WAN = 176.31.123.109;
@def $DEV_WAN = eth0;

# guests : virtual machines
@def $NET_VMS = 178.33.6.208/28;
@def $DEV_VMS = vmbr1;
@def $NET_VMS_PRIVATE = 192.168.0.0/16;
@def $DEV_VMS_PRIVATE = venet0;

# whitelisted services = IP and port knocking
@def $EO_WHITELIST_IPS = `bash -c '. /etc/firewall/default_eo ; echo ${WHITELIST_EO[@]}'`;
@def $WHITELIST_IPS = ($EO_WHITELIST_IPS);
@def $KNOCK1 = 100;
@def $KNOCK2 = 200;
@def $KNOCK3 = 301;

# WAN services
@def $DNS_ON_WAN = 1;
@def $WEB_ON_WAN = (80 443); # HTTP, HTTPS
@def $MAIL_ON_WAN = (25 587 993 995 4190); # SMTP, submission, IMAPS, POPS, SIEVE
@def $WHITELIST_WAN = (ssh 8006 3128 5900:5999); # SSH + proxmox (8006=web, 3128=spice, 5900:5999=vnc)

# global VMS services
@def $WEB_ON_VMS = (80 443);
@def $WHITELIST_VMS = (ssh);

# supervision servers (munin, nagios)
@def $SUPERVISORS = (212.85.154.22 88.190.46.145);

@include 'config.d/';
@include 'pre.d/';

# $VMS = 1 if there are VMs with public IPs
@def $VMS = 0;
@if $NET_VMS @if $DEV_VMS @def $VMS = 1;
# $VMS = 1 if there are VMs with private IPs
@def $VMS_PRIVATE = 0;
@if $NET_VMS_PRIVATE @if $DEV_VMS_PRIVATE @def $VMS_PRIVATE = 1;

# output some debug informations
@hook pre  "# (c) entr'ouvert";
@hook post "# VMS = $VMS";
@hook post "# VMS_PRIVATE = $VMS_PRIVATE";

table filter {
    chain INPUT {
        policy DROP;

        # allow all local traffic
        interface lo ACCEPT;

        # connection tracking
        mod state state INVALID DROP;
        mod state state (ESTABLISHED RELATED) ACCEPT;

        # accept ping request
        proto icmp icmp-type echo-request ACCEPT;

        # local services
        interface $DEV_WAN daddr $IP_WAN mod state state NEW {
            # DNS requests
            @if $DNS_ON_WAN proto (udp tcp) dport 53
                mod comment comment "DNS on WAN"
                ACCEPT;
            # Web
            @if $WEB_ON_WAN proto tcp mod multiport destination-ports $WEB_ON_WAN
                mod comment comment "Web on WAN"
                ACCEPT;
            # Mail
            @if $MAIL_ON_WAN proto tcp mod multiport destination-ports $MAIL_ON_WAN
                mod comment comment "Mail services on WAN"
                ACCEPT;
            # munin & nagios
            @if $SUPERVISORS saddr $SUPERVISORS proto tcp mod multiport destination-ports (4949 5666)
                mod comment comment "Munin&Nagios on WAN"
                ACCEPT;
            # allow connections (SSH, proxmox, etc.) from whitelisted IPs
            proto tcp mod multiport destination-ports $WHITELIST_WAN
                jump whitelist;
        }

        # port knocking interception
        interface $DEV_WAN daddr $IP_WAN protocol tcp jump knock;
    }

    chain OUTPUT {
        policy DROP;

        # allow all local traffic
        interface lo ACCEPT;

        # connection tracking
        mod state state INVALID DROP;
        mod state state (ESTABLISHED RELATED) ACCEPT;

        proto tcp mod multiport destination-ports (53 22 80 443)
            mod state state NEW
            ACCEPT;
        proto udp dport 53
            mod state state NEW
            ACCEPT;
        proto icmp icmp-type echo-request ACCEPT;
    }

    chain FORWARD {
        policy DROP;

        # connection tracking
        mod state state INVALID DROP;
        mod state state (ESTABLISHED RELATED) ACCEPT;

        # accept ping request
        proto icmp icmp-type echo-request ACCEPT;

        # from VMS to Internet: ssh, web, dns, ping
        outerface $DEV_WAN {
            proto tcp mod multiport destination-ports (53 22 80 443)
                mod state state NEW
                ACCEPT;
            proto udp dport 53
                mod state state NEW
                ACCEPT;
            proto icmp icmp-type echo-request ACCEPT;
        }

        # Web on VMs
        @if $WEB_ON_VMS
            protocol tcp
            mod comment comment "Web on VMs"
            mod multiport destination-ports $WEB_ON_VMS
            mod state state NEW {
                @if $VMS daddr $NET_VMS outerface $DEV_VMS ACCEPT;
                @if $VMS_PRIVATE daddr $NET_VMS_PRIVATE outerface $DEV_VMS_PRIVATE ACCEPT;
            }

        # private VMs
        @if $VMS_PRIVATE daddr $NET_VMS_PRIVATE outerface $DEV_VMS_PRIVATE {
            # connections (SSH, etc.) from host
            @if $WHITELIST_VMS interface $DEV_WAN protocol tcp
                mod multiport destination-ports $WHITELIST_VMS
                mod state state NEW
                ACCEPT;
        }

        # public VMs
        @if $VMS daddr $NET_VMS outerface $DEV_VMS {
            # nagios
            @if $SUPERVISORS saddr $SUPERVISORS
                protocol tcp
                mod multiport destination-ports (4949 5666)
                mod state state NEW
                mod comment comment "Munin&Nagios on VMs"
                ACCEPT;
            # connections (SSH, etc.) from whitelisted IPs
            # + port knocking
            @if $WHITELIST_VMS protocol tcp {
                mod multiport destination-ports $WHITELIST_VMS
                mod state state NEW jump whitelist;
                jump knock;
            }
        }

    }

    # accept from EO & port-knock source IP
    chain whitelist {
        saddr $WHITELIST_IPS ACCEPT;
        mod recent rcheck name "knock3" seconds 15 ACCEPT;
    }

    # port knocking (add IP in the whitelist for 15 seconds)
    chain knock {
        protocol tcp {
            dport $KNOCK1 mod recent set name "knock1" NOP;
            dport $KNOCK2 mod recent rcheck name "knock1" seconds 3 @subchain "knock2" {
                    mod recent name "knock1" remove NOP;
                    mod recent name "knock2" set NOP;
                }
            dport $KNOCK3 mod recent rcheck name "knock2" seconds 3 @subchain "knock3" {
                    mod recent name "knock2" remove NOP;
                    mod recent name "knock3" set NOP;
            }
        }
    }

}

# SNAT for private VMs
@if $VMS_PRIVATE table nat chain POSTROUTING
    saddr $NET_VMS_PRIVATE
    outerface $DEV_WAN
    SNAT to $IP_WAN;

@include 'local.d/';
@include 'post.d/';