2012-01-10

DNAT szabályok tűzfalazása Vyatta alatt

Rég nem volt már teljes egészében Vyattának szentelt írás az oldalon, a napokban épp szóba is került a rendszernek egy érdekesebb tulajdonsága a munkahelyemen, így most semmi sem tarthat vissza attól, hogy mindazt, amiről ott szó volt, közzé ne tegyem. Alapvetően egyszerű dologról van szó, a Vyatta port forwarding vagy DNAT lehetőségéről, ami kombinálva némi szűréssel, könnyen káromkodásba fordulhat (megjegyzem, minden Linux rendszeren ugyanezen szisztéma szerint működik a DNAT). Mi is ez az egész pontosan? Íme a Vyatta dokumentációból kiollózott ábra, mely az egyes NAT alrendszerek, a routing folyamat és a tűzfalazás viszonyát szemlélteti:


Az ábrán a témánk szempontjából két fontos dolgot láthatunk, az egyik az, hogy a DNAT (destination NAT, avagy port forwarding, esetleg szolgáltatás publikálás) minden egyéb feldolgozási folyamat, routeolás, szűrés előtt történik meg egy beérkező csomagon. Ezzel szemben az SNAT (source NAT) a legutolsó lépés, ami csak a routeolás és a tűzfalazás után történik. A szűrés szempontjából az SNAT sima ügy, bejön a klienstől a csomag mondjuk a 192.168.0.100-as forrás IP-vel, a célcím nem a Vyatta rendszer (Dest=local? No), a tűzfal szépen átkergeti az IN, majd az OUT irányú szabályokon, végül az SNAT dobozkában leszerelik róla a 192.168.0.100-as feladói címet és ráhegesztik mondjuk feladóként az 1.2.3.4 publikus címet, illetve ezt fel is jegyzik egy táblázatba, hogy a visszatérő forgalmat le lehessen kezelni és eljusson az eredeti feladóhoz.

A DNAT egy kicsit más, arról van ugye szó, hogy az 1.2.3.4-re irányuló, pl. TCP 80-as forgalmat valójában nem a Vyatta webszervere emésztgeti, hanem a mögötte lévő NAT-olt hálóban mondjuk a 192.168.0.101-es host. Bemegy a DNAT dobozba a 1.2.3.4:80-ra küldött üzenet, odabent átalakul, és ami kijön, annak már 192.168.0.101:80 lesz a célja. Persze a dobozban ezt a csereberét megintcsak jól feljegyzik. Ezek után a routing megmondja, hogy ez a 192.168.0.101 a Vyatta LAN oldalán található cím (Dest=local? No), átmegy az IN, majd az OUT szűrőn, és kimegy a LAN-ba.

Mindez azért érdekes, mert az ember - főképp, ha vállalati tűzfalak GUI-jához szokott - a tűzfalszabályok írásakor alapból nincs NAT üzemmódban, és egy ilyen DNAT-olt 80-as portot simán úgy vesz fel a Vyatta tűzfalszabályokban, hogy a külső IP címmel számol, az 1.2.3.4:80-ra engedi be a népeket, pedig mire a tűzfalhoz eljut az 1.2.3.4:80-as csomag, addigra az már keresztülverekedte magát a DNAT-on, és 192.168.0.101:80 van benne.

Következzék egy konkrét konfig példa, ami kívülről elérhetővé teszi az 1.2.3.4:22-es és 1.2.3.4:80-as TCP portokat, a különbség annyi, hogy az SSH a Vyattán fut, a HTTP viszont NAT mögött, másik hoston. A Vyatta külső interfészének (eth0) bejövő szűrőjében mégis egy privát, belső IP cím szerepel:

firewall {
    name INET_to_INTERNAL {
        default-action drop
        rule 100 {
            action accept
            description "Allowing HTTP traffic to internal host 101"
            destination {
                address 192.168.0.101
                port 80
            }
            protocol tcp
        }
    }
    name INET_to_LOCAL {
        default-action drop
        rule 100 {
            action accept
            protocol icmp
        }
        rule 200 {
            action accept
            description "SSH access on port 22"
            destination {
                address 1.2.3.4
                port 22
            }
            protocol tcp
        }
    }
}
interfaces {
    ethernet eth0 {
        address 1.2.3.4/24
        firewall {
            in {
                name INET_to_INTERNAL
            }
            local {
                name INET_to_LOCAL
            }
        }
    }
    ethernet eth1 {
        address 192.168.1.1/24
    }
    loopback lo {
    }
}
protocols {
    static {
        route 0.0.0.0/0 {
            next-hop 1.2.3.1 {
            }
        }
    }
}
service {
    nat {
        rule 100 {
            description "DNAT for HTTP on 192.168.0.101"
            destination {
                address 1.2.3.4
                port 80
            }
            inbound-interface eth0
            inside-address {
                address 192.168.0.101
            }
            protocol tcp
            type destination
        }
        rule 200 {
            description "SNAT for internal subnet"
            outbound-interface eth0
            outside-address {
                address 1.2.3.4
            }
            source {
                address 192.168.0.0/24
            }
            type source
        }
    }
    ssh {
        port 22
        protocol-version v2
    }
}

2 megjegyzés: