108
108
if policy == "allow":
109
self.set_default(self.files['defaults'], \
110
self.set_default(self.files['defaults'], \
110
111
"DEFAULT_%s_POLICY" % (chain), \
112
115
old_log_str = 'UFW BLOCK'
113
116
new_log_str = 'UFW ALLOW'
114
117
elif policy == "reject":
115
self.set_default(self.files['defaults'], \
119
self.set_default(self.files['defaults'], \
116
120
"DEFAULT_%s_POLICY" % (chain), \
118
124
old_log_str = 'UFW ALLOW'
119
125
new_log_str = 'UFW BLOCK'
121
self.set_default(self.files['defaults'], \
128
self.set_default(self.files['defaults'], \
122
129
"DEFAULT_%s_POLICY" % (chain), \
124
133
old_log_str = 'UFW ALLOW'
125
134
new_log_str = 'UFW BLOCK'
136
145
for line in fns['orig']:
137
146
if pat.search(line):
138
os.write(fd, pat.sub(new_log_str, line))
147
ufw.util.write_to_file(fd, pat.sub(new_log_str, line))
149
ufw.util.write_to_file(fd, line)
142
ufw.util.close_files(fns)
152
ufw.util.close_files(fns)
144
156
rstr = _("Default %(direction)s policy changed to '%(policy)s'\n") % \
145
157
({'direction': direction, 'policy': policy})
597
609
rules_file = self.files['rules6']
611
# Perform this here so we can present a nice error to the user rather
613
if not os.access(rules_file, os.W_OK):
614
err_msg = _("'%s' is not writable" % (rules_file))
615
raise UFWError(err_msg)
600
618
fns = ufw.util.open_files(rules_file)
601
619
except Exception:
616
os.write(fd, "*filter\n")
617
os.write(fd, ":" + chain_prefix + "-user-input - [0:0]\n")
618
os.write(fd, ":" + chain_prefix + "-user-output - [0:0]\n")
619
os.write(fd, ":" + chain_prefix + "-user-forward - [0:0]\n")
634
ufw.util.write_to_file(fd, "*filter\n")
635
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-input - [0:0]\n")
636
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-output - [0:0]\n")
637
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-forward - [0:0]\n")
639
ufw.util.write_to_file(fd, ":" + chain_prefix + "-before-logging-input - [0:0]\n")
640
ufw.util.write_to_file(fd, ":" + chain_prefix + "-before-logging-output - [0:0]\n")
641
ufw.util.write_to_file(fd, ":" + chain_prefix + "-before-logging-forward - [0:0]\n")
642
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-logging-input - [0:0]\n")
643
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-logging-output - [0:0]\n")
644
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-logging-forward - [0:0]\n")
645
ufw.util.write_to_file(fd, ":" + chain_prefix + "-after-logging-input - [0:0]\n")
646
ufw.util.write_to_file(fd, ":" + chain_prefix + "-after-logging-output - [0:0]\n")
647
ufw.util.write_to_file(fd, ":" + chain_prefix + "-after-logging-forward - [0:0]\n")
648
ufw.util.write_to_file(fd, ":" + chain_prefix + "-logging-deny - [0:0]\n")
649
ufw.util.write_to_file(fd, ":" + chain_prefix + "-logging-allow - [0:0]\n")
621
651
if chain_prefix == "ufw":
622
652
# Rate limiting only supported with IPv4
623
os.write(fd, ":" + chain_prefix + "-user-limit - [0:0]\n")
624
os.write(fd, ":" + chain_prefix + "-user-limit-accept - [0:0]\n")
653
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-limit - [0:0]\n")
654
ufw.util.write_to_file(fd, ":" + chain_prefix + "-user-limit-accept - [0:0]\n")
626
os.write(fd, "### RULES ###\n")
656
ufw.util.write_to_file(fd, "### RULES ###\n")
639
669
tstr += "_%s" % (r.interface_in)
640
670
if r.interface_out != "":
641
671
tstr += "_%s" % (r.interface_out)
642
os.write(fd, tstr + "\n")
672
ufw.util.write_to_file(fd, tstr + "\n")
644
674
pat_space = re.compile(' ')
656
686
tstr += "_%s" % (r.interface_in)
657
687
if r.interface_out != "":
658
688
tstr += "_%s" % (r.interface_out)
659
os.write(fd, tstr + "\n")
689
ufw.util.write_to_file(fd, tstr + "\n")
661
691
chain_suffix = "input"
662
692
if r.direction == "out":
667
697
for s in self._get_rules_from_formatted(rule_str, chain_prefix, \
699
ufw.util.write_to_file(fd, s)
672
os.write(fd, "\n### END RULES ###\n")
702
ufw.util.write_to_file(fd, "\n### END RULES ###\n")
704
# Add logging rules, skipping any delete ('-D') rules
705
ufw.util.write_to_file(fd, "\n### LOGGING ###\n")
707
lrules_t = self._get_logging_rules(self.defaults['loglevel'])
710
for c, r, q in lrules_t:
711
if len(r) > 0 and r[0] == '-D':
713
if c.startswith(chain_prefix + "-"):
714
ufw.util.write_to_file(fd,
715
" ".join(r).replace('[', '"[').replace('] ', '] "') + \
717
ufw.util.write_to_file(fd, "### END LOGGING ###\n")
674
719
if chain_prefix == "ufw":
720
ufw.util.write_to_file(fd, "\n### RATE LIMITING ###\n")
675
721
# Rate limiting only supported with IPv4
676
os.write(fd, "-A " + chain_prefix + "-user-limit -m limit " + \
722
ufw.util.write_to_file(fd, "-A " + chain_prefix + "-user-limit -m limit " + \
677
723
"--limit 3/minute -j LOG --log-prefix " + \
678
724
"\"[UFW LIMIT BLOCK] \"\n")
679
os.write(fd, "-A " + chain_prefix + "-user-limit -j REJECT\n")
680
os.write(fd, "-A " + chain_prefix + "-user-limit-accept -j ACCEPT\n")
682
os.write(fd, "COMMIT\n")
685
ufw.util.close_files(fns, False)
687
ufw.util.close_files(fns)
725
ufw.util.write_to_file(fd, "-A " + chain_prefix + "-user-limit -j REJECT\n")
726
ufw.util.write_to_file(fd, "-A " + chain_prefix + "-user-limit-accept -j ACCEPT\n")
727
ufw.util.write_to_file(fd, "### END RATE LIMITING ###\n")
729
ufw.util.write_to_file(fd, "COMMIT\n")
733
ufw.util.close_files(fns, False)
735
ufw.util.close_files(fns)
689
739
def set_rule(self, rule, allow_reload=True):
690
740
'''Updates firewall with rule by:
932
983
if not self._is_enabled():
935
if level not in self.loglevels.keys():
936
err_msg = _("Invalid log level '%s'") % (level)
937
raise UFWError(err_msg)
988
rules_t = self._get_logging_rules(level)
992
# Update the user rules file
994
self._write_rules(v6=False)
995
self._write_rules(v6=True)
999
err_msg = _("Couldn't update rules file for logging")
939
1002
# make sure all the chains are here, it's redundant but helps make
940
1003
# sure the chains are in a consistent state
956
1019
raise UFWError(err_msg)
1021
# Add logging rules to running firewall
1022
for c, r, q in rules_t:
1024
if len(r) > 0 and r[0] == '-D':
1027
if q == 'delete_first' and len(r) > 1:
1028
self._chain_cmd(c, ['-D'] + r[1:], fail_ok=True)
1029
self._chain_cmd(c, r, fail_ok)
1031
raise UFWError(err_msg)
1033
def _get_logging_rules(self, level):
1034
'''Get rules for specified logging level'''
1037
if level not in self.loglevels.keys():
1038
err_msg = _("Invalid log level '%s'") % (level)
1039
raise UFWError(err_msg)
958
1041
if level == "off":
959
1042
# when off, insert a RETURN rule at the top of user rules, thus
960
1043
# preserving the rules
961
1044
for c in self.chains['user']:
962
self._chain_cmd(c, ['-D', c, '-j', 'RETURN'], fail_ok=True)
963
self._chain_cmd(c, ['-I', c, '-j', 'RETURN'])
1045
rules_t.append([c, ['-I', c, '-j', 'RETURN'], 'delete_first'])
966
1048
# when on, remove the RETURN rule at the top of user rules, thus
967
1049
# honoring the log rules
968
1050
for c in self.chains['user']:
969
self._chain_cmd(c, ['-D', c, '-j', 'RETURN'], fail_ok=True)
1051
rules_t.append([c, ['-D', c, '-j', 'RETURN'], ''])
971
1053
limit_args = ['-m', 'limit', '--limit', '3/min', '--limit-burst', '10']
983
1065
if self.get_default_policy(t) == "reject" or \
984
1066
self.get_default_policy(t) == "deny":
985
1067
msg = "[UFW BLOCK] "
987
self._chain_cmd(c, ['-A', c, '-j', 'LOG', \
988
'--log-prefix', msg] + largs)
1068
rules_t.append([c, ['-A', c, '-j', 'LOG', \
1069
'--log-prefix', msg] +
991
1071
elif self.loglevels[level] >= self.loglevels["medium"]:
992
1072
msg = "[UFW ALLOW] "
994
self._chain_cmd(c, ['-A', c, '-j', 'LOG', \
995
'--log-prefix', msg] + largs)
1073
rules_t.append([c, ['-A', c, '-j', 'LOG', \
1074
'--log-prefix', msg] + largs, ''])
999
1076
# Setup the miscellaneous logging chains
1007
1084
msg = "[UFW ALLOW] "
1008
1085
elif c.endswith("deny"):
1009
1086
msg = "[UFW BLOCK] "
1010
if self.loglevels[level] >= self.loglevels["medium"]:
1087
if self.loglevels[level] < self.loglevels["medium"]:
1011
1088
# only log INVALID in medium and higher
1013
self._chain_cmd(c, ['-I', c, '-m', 'state', \
1014
'--state', 'INVALID', \
1015
'-j', 'RETURN'] + largs)
1019
self._chain_cmd(c, ['-A', c, '-j', 'LOG', \
1020
'--log-prefix', msg] + largs)
1089
rules_t.append([c, ['-I', c, '-m', 'state', \
1090
'--state', 'INVALID', \
1091
'-j', 'RETURN'] + largs, ''])
1092
rules_t.append([c, ['-A', c, '-j', 'LOG', \
1093
'--log-prefix', msg] + largs, ''])
1024
1095
# Setup the audit logging chains
1025
1096
if self.loglevels[level] >= self.loglevels["medium"]:
1037
1108
msg = "[UFW AUDIT] "
1038
1109
for c in self.chains['before']:
1040
self._chain_cmd(c, ['-I', c, '-j', 'LOG', \
1041
'--log-prefix', msg] + largs)
1043
raise UFWError(err_msg)
1110
rules_t.append([c, ['-I', c, '-j', 'LOG', \
1111
'--log-prefix', msg] + largs, ''])