From 3abf0af94cd7cf4d0c0666a40deff43ca590a597 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Mon, 29 Feb 2016 08:59:58 +0100 Subject: Firewall: separate Table and Target (cherry picked from commit c97f1308739aa7877aac2f3c949c4aadf2266775) --- src/Propellor/Property/Firewall.hs | 125 +++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 60 deletions(-) (limited to 'src/Propellor/Property/Firewall.hs') diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index eefc8342..62adf33a 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -7,11 +7,7 @@ module Propellor.Property.Firewall ( installed, Chain(..), Table(..), - TargetFilter(..), - TargetNat(..), - TargetMangle(..), - TargetRaw(..), - TargetSecurity(..), + Target(..), Proto(..), Rules(..), ConnectionState(..), @@ -30,10 +26,10 @@ import qualified Propellor.Property.Network as Network installed :: Property NoInfo installed = Apt.installed ["iptables"] -rule :: Chain -> Table -> Rules -> Property NoInfo -rule c t rs = property ("firewall rule: " <> show r) addIpTable +rule :: Chain -> Table -> Target -> Rules -> Property NoInfo +rule c tb tg rs = property ("firewall rule: " <> show r) addIpTable where - r = Rule c t rs + r = Rule c tb tg rs addIpTable = liftIO $ do let args = toIpTable r exist <- boolSystem "iptables" (chk args) @@ -45,8 +41,9 @@ rule c t rs = property ("firewall rule: " <> show r) addIpTable toIpTable :: Rule -> [CommandParam] toIpTable r = map Param $ - show (ruleChain r) : - toIpTableArg (ruleRules r) ++ toIpTableTable (ruleTable r) + fromChain (ruleChain r) : + toIpTableArg (ruleRules r) ++ + ["-t", fromTable (ruleTable r), "-j", fromTarget (ruleTarget r)] toIpTableArg :: Rules -> [String] toIpTableArg Everything = [] @@ -80,78 +77,86 @@ fromIPWithMask (IPWithIPMask ip ipm) = fromIPAddr ip ++ "/" ++ fromIPAddr ipm fromIPWithMask (IPWithNumMask ip m) = fromIPAddr ip ++ "/" ++ show m data Rule = Rule - { ruleChain :: Chain - , ruleTable :: Table - , ruleRules :: Rules + { ruleChain :: Chain + , ruleTable :: Table + , ruleTarget :: Target + , ruleRules :: Rules } deriving (Eq, Show) -data Table = Filter TargetFilter | Nat TargetNat | Mangle TargetMangle | Raw TargetRaw | Security TargetSecurity +data Table = Filter | Nat | Mangle | Raw | Security deriving (Eq, Show) -toIpTableTable :: Table -> [String] -toIpTableTable f = ["-t", table, "-j", target] - where - (table, target) = toIpTableTable' f - -toIpTableTable' :: Table -> (String, String) -toIpTableTable' (Filter target) = ("filter", fromTarget target) -toIpTableTable' (Nat target) = ("nat", fromTarget target) -toIpTableTable' (Mangle target) = ("mangle", fromTarget target) -toIpTableTable' (Raw target) = ("raw", fromTarget target) -toIpTableTable' (Security target) = ("security", fromTarget target) +fromTable :: Table -> String +fromTable Filter = "filter" +fromTable Nat = "nat" +fromTable Mangle = "mangle" +fromTable Raw = "raw" +fromTable Security = "security" -data Chain = INPUT | OUTPUT | FORWARD +data Target = ACCEPT | REJECT | DROP | LOG | TargetCustom String deriving (Eq, Show) -data TargetFilter = ACCEPT | REJECT | DROP | LOG | FilterCustom String +fromTarget :: Target -> String +fromTarget ACCEPT = "ACCEPT" +fromTarget REJECT = "REJECT" +fromTarget DROP = "DROP" +fromTarget LOG = "LOG" +fromTarget (TargetCustom t) = t + +data Chain = ChainFilter | ChainNat | ChainMangle | ChainRaw | ChainSecurity deriving (Eq, Show) -class FromTarget a where - fromTarget :: a -> String +instance FromChain Chain where + fromChain = fromChain + +class FromChain a where + fromChain :: a -> String + +data ChainFilter = INPUT | OUTPUT | FORWARD | FilterCustom String + deriving (Eq, Show) -instance FromTarget TargetFilter where - fromTarget ACCEPT = "ACCEPT" - fromTarget REJECT = "REJECT" - fromTarget DROP = "DROP" - fromTarget LOG = "LOG" - fromTarget (FilterCustom f) = f +instance FromChain ChainFilter where + fromChain INPUT = "INPUT" + fromChain OUTPUT = "OUTPUT" + fromChain FORWARD = "FORWARD" + fromChain (FilterCustom c) = c -data TargetNat = NatPREROUTING | NatOUTPUT | NatPOSTROUTING | NatCustom String +data ChainNat = NatPREROUTING | NatOUTPUT | NatPOSTROUTING | NatCustom String deriving (Eq, Show) -instance FromTarget TargetNat where - fromTarget NatPREROUTING = "PREROUTING" - fromTarget NatOUTPUT = "OUTPUT" - fromTarget NatPOSTROUTING = "POSTROUTING" - fromTarget (NatCustom f) = f +instance FromChain ChainNat where + fromChain NatPREROUTING = "PREROUTING" + fromChain NatOUTPUT = "OUTPUT" + fromChain NatPOSTROUTING = "POSTROUTING" + fromChain (NatCustom f) = f -data TargetMangle = ManglePREROUTING | MangleOUTPUT | MangleINPUT | MangleFORWARD | ManglePOSTROUTING | MangleCustom String +data ChainMangle = ManglePREROUTING | MangleOUTPUT | MangleINPUT | MangleFORWARD | ManglePOSTROUTING | MangleCustom String deriving (Eq, Show) -instance FromTarget TargetMangle where - fromTarget ManglePREROUTING = "PREROUTING" - fromTarget MangleOUTPUT = "OUTPUT" - fromTarget MangleINPUT = "INPUT" - fromTarget MangleFORWARD = "FORWARD" - fromTarget ManglePOSTROUTING = "POSTROUTING" - fromTarget (MangleCustom f) = f +instance FromChain ChainMangle where + fromChain ManglePREROUTING = "PREROUTING" + fromChain MangleOUTPUT = "OUTPUT" + fromChain MangleINPUT = "INPUT" + fromChain MangleFORWARD = "FORWARD" + fromChain ManglePOSTROUTING = "POSTROUTING" + fromChain (MangleCustom f) = f -data TargetRaw = RawPREROUTING | RawOUTPUT | RawCustom String +data ChainRaw = RawPREROUTING | RawOUTPUT | RawCustom String deriving (Eq, Show) -instance FromTarget TargetRaw where - fromTarget RawPREROUTING = "PREROUTING" - fromTarget RawOUTPUT = "OUTPUT" - fromTarget (RawCustom f) = f +instance FromChain ChainRaw where + fromChain RawPREROUTING = "PREROUTING" + fromChain RawOUTPUT = "OUTPUT" + fromChain (RawCustom f) = f -data TargetSecurity = SecurityINPUT | SecurityOUTPUT | SecurityFORWARD | SecurityCustom String +data ChainSecurity = SecurityINPUT | SecurityOUTPUT | SecurityFORWARD | SecurityCustom String deriving (Eq, Show) -instance FromTarget TargetSecurity where - fromTarget SecurityINPUT = "INPUT" - fromTarget SecurityOUTPUT = "OUTPUT" - fromTarget SecurityFORWARD = "FORWARD" - fromTarget (SecurityCustom f) = f +instance FromChain ChainSecurity where + fromChain SecurityINPUT = "INPUT" + fromChain SecurityOUTPUT = "OUTPUT" + fromChain SecurityFORWARD = "FORWARD" + fromChain (SecurityCustom f) = f data Proto = TCP | UDP | ICMP deriving (Eq, Show) -- cgit v1.2.3 From 60a7dfeb65b72e2ef26e071c007f9d11fe9aebc2 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Mon, 29 Feb 2016 09:20:24 +0100 Subject: Firewall: add ICMPTypeMatch (cherry picked from commit 2214aca8f3ca92b9739b2884cb59274edad9170e) --- src/Propellor/Property/Firewall.hs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/Propellor/Property/Firewall.hs') diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index 62adf33a..05d70f45 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -11,6 +11,7 @@ module Propellor.Property.Firewall ( Proto(..), Rules(..), ConnectionState(..), + ICMPTypeMatch(..), IPWithMask(..), fromIPWithMask ) where @@ -58,6 +59,11 @@ toIpTableArg (Ctstate states) = , "conntrack" , "--ctstate", intercalate "," (map show states) ] +toIpTableArg (ICMPType i) = + [ "-m" + , "icmp" + , "--icmp-type", fromICMPTypeMatch i + ] toIpTableArg (Source ipwm) = [ "-s" , intercalate "," (map fromIPWithMask ipwm) @@ -164,6 +170,13 @@ data Proto = TCP | UDP | ICMP data ConnectionState = ESTABLISHED | RELATED | NEW | INVALID deriving (Eq, Show) +data ICMPTypeMatch = ICMPTypeName String | ICMPTypeCode Int + deriving (Eq, Show) + +fromICMPTypeMatch :: ICMPTypeMatch -> String +fromICMPTypeMatch (ICMPTypeName t) = t +fromICMPTypeMatch (ICMPTypeCode c) = show c + data Rules = Everything | Proto Proto @@ -174,6 +187,7 @@ data Rules | InIFace Network.Interface | OutIFace Network.Interface | Ctstate [ ConnectionState ] + | ICMPType ICMPTypeMatch | Source [ IPWithMask ] | Destination [ IPWithMask ] | Rules :- Rules -- ^Combine two rules -- cgit v1.2.3 From 02edd1dca9b5554728201924a8ed786133b1c57d Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Mon, 29 Feb 2016 09:48:46 +0100 Subject: Firewall: add Frequency (cherry picked from commit 26fd68a9cda543e74492dc71680d10eaa881f351) --- src/Propellor/Property/Firewall.hs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/Propellor/Property/Firewall.hs') diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index 05d70f45..01664130 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -12,6 +12,7 @@ module Propellor.Property.Firewall ( Rules(..), ConnectionState(..), ICMPTypeMatch(..), + Frequency(..), IPWithMask(..), fromIPWithMask ) where @@ -64,6 +65,11 @@ toIpTableArg (ICMPType i) = , "icmp" , "--icmp-type", fromICMPTypeMatch i ] +toIpTableArg (RateLimit f) = + [ "-m" + , "limit" + , "--limit", fromFrequency f + ] toIpTableArg (Source ipwm) = [ "-s" , intercalate "," (map fromIPWithMask ipwm) @@ -177,6 +183,12 @@ fromICMPTypeMatch :: ICMPTypeMatch -> String fromICMPTypeMatch (ICMPTypeName t) = t fromICMPTypeMatch (ICMPTypeCode c) = show c +data Frequency = NumBySecond Int + deriving (Eq, Show) + +fromFrequency :: Frequency -> String +fromFrequency (NumBySecond n) = show n ++ "/second" + data Rules = Everything | Proto Proto @@ -188,6 +200,7 @@ data Rules | OutIFace Network.Interface | Ctstate [ ConnectionState ] | ICMPType ICMPTypeMatch + | RateLimit Frequency | Source [ IPWithMask ] | Destination [ IPWithMask ] | Rules :- Rules -- ^Combine two rules -- cgit v1.2.3 From 140fb642e8ea3492313d3f41ef44930e1974b3f9 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Mon, 29 Feb 2016 18:03:12 +0100 Subject: Firewall: add TCPFlag (cherry picked from commit f16e0e4f632032c70adcb9ba9f108e87a6ae4321) --- src/Propellor/Property/Firewall.hs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/Propellor/Property/Firewall.hs') diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index 01664130..bf41cf20 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -70,6 +70,13 @@ toIpTableArg (RateLimit f) = , "limit" , "--limit", fromFrequency f ] +toIpTableArg (TCPFlags m c) = + [ "-m" + , "tcp" + , "--tcp-flags" + , intercalate "," (map show m) + , intercalate "," (map show c) + ] toIpTableArg (Source ipwm) = [ "-s" , intercalate "," (map fromIPWithMask ipwm) @@ -189,6 +196,13 @@ data Frequency = NumBySecond Int fromFrequency :: Frequency -> String fromFrequency (NumBySecond n) = show n ++ "/second" +type TCPFlagMask = [TCPFlag] + +type TCPFlagComp = [TCPFlag] + +data TCPFlag = SYN | ACK | FIN | RST | URG | PSH | ALL | NONE + deriving (Eq, Show) + data Rules = Everything | Proto Proto @@ -201,6 +215,7 @@ data Rules | Ctstate [ ConnectionState ] | ICMPType ICMPTypeMatch | RateLimit Frequency + | TCPFlags TCPFlagMask TCPFlagComp | Source [ IPWithMask ] | Destination [ IPWithMask ] | Rules :- Rules -- ^Combine two rules -- cgit v1.2.3 From 91cc571b2d6947acd70717157cd1b24819202997 Mon Sep 17 00:00:00 2001 From: Félix Sipma Date: Mon, 29 Feb 2016 18:05:24 +0100 Subject: Firewall: add TCPSyn to Rules (cherry picked from commit 864bff7743bd3a77f1bfdb37bdeeea49e31e1f52) --- src/Propellor/Property/Firewall.hs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/Propellor/Property/Firewall.hs') diff --git a/src/Propellor/Property/Firewall.hs b/src/Propellor/Property/Firewall.hs index bf41cf20..c4d2ee1b 100644 --- a/src/Propellor/Property/Firewall.hs +++ b/src/Propellor/Property/Firewall.hs @@ -77,6 +77,7 @@ toIpTableArg (TCPFlags m c) = , intercalate "," (map show m) , intercalate "," (map show c) ] +toIpTableArg TCPSyn = ["--syn"] toIpTableArg (Source ipwm) = [ "-s" , intercalate "," (map fromIPWithMask ipwm) @@ -216,6 +217,7 @@ data Rules | ICMPType ICMPTypeMatch | RateLimit Frequency | TCPFlags TCPFlagMask TCPFlagComp + | TCPSyn | Source [ IPWithMask ] | Destination [ IPWithMask ] | Rules :- Rules -- ^Combine two rules -- cgit v1.2.3