Compare commits

...

19 commits

Author SHA1 Message Date
Gregory Colpart
334229b1f1 confusion :/ 2025-01-02 16:14:06 +01:00
Gregory Colpart
18dd0d57ef fix errors (IPv4->IPv4/IPv6) and add infos in SERVICESTCP* comments 2025-01-02 15:35:59 +01:00
Gregory Colpart
40ea8c4cfd on passe à ipset 2024-11-09 18:18:14 +01:00
Gregory Colpart
67e8ad9f85 ajout d'un script pour blacklister tout Asie/Pacifique 2024-11-09 13:53:48 +01:00
70d3790337
Update default config with Evolix IPv6 addresses 2024-11-05 15:04:58 +01:00
Gregory Colpart
133ba0a75c add scripts to block IPv4 ranges with AS numbers 2024-07-31 00:48:53 +02:00
dffbeb547a
Update changelog 2024-07-11 18:07:26 +02:00
dccdb78b35
Bump version 2024-07-11 16:32:34 +02:00
Gregory Colpart
7d55ca06d1 RELATED is not needed and could be a security problem : https://gist.github.com/azlux/6a70bd38bb7c525ab26efe7e3a7ea8ac 2024-04-26 11:56:17 +02:00
2e40dfb33e
Ensure chain MINIFW-DOCKER-INPUT-MANUAL exists before execution of includes/config files 2024-04-18 16:51:31 +02:00
0c995a94d8
Chain MINIFW-DOCKER-INPUT-MANUAL for more granular/manual filtering of incoming traffic to services inside docker 2024-04-18 16:32:53 +02:00
2bdcf01882
add IPv6 for secondary office network 2023-07-07 10:26:35 +02:00
5eb3129e47
fix monitoring IPv6 2023-07-07 10:25:42 +02:00
3cf9d87f72
Check SAFETY_TIMER value 2023-07-06 16:44:39 +02:00
bbe83486b8
Add colors to safe-start action 2023-07-06 16:33:55 +02:00
f7064eeac8
Improve messages 2023-07-05 12:35:55 +02:00
e17ce14a67
fix interactive mode detection 2023-07-05 12:35:32 +02:00
54fa2ea8eb
Add safe-start and safe-restart
These commands will run a background safety check to stop the firewall if a safety lock is removed in 30 seconds.
This will reduce the risk to get locked out because of a bad configuration.
2023-07-05 12:18:44 +02:00
64fd067ce9
add message type in output 2023-07-04 17:22:59 +02:00
6 changed files with 214 additions and 22 deletions

View file

@ -15,6 +15,28 @@ and this project **does not adhere to [Semantic Versioning](http://semver.org/sp
### Security
## [24.07] - 2024-07-11
### Added
* safe-start and safe-restart
* Chain MINIFW-DOCKER-INPUT-MANUAL for more granular/manual filtering of incoming traffic to services inside docker
### Changed
### Deprecated
### Removed
* Removed RELATED state match
### Fixed
* fix interactive mode detection
### Security
## [23.07] - 2023-07-04
### Added

25
blacklist-as.sh Normal file
View file

@ -0,0 +1,25 @@
#!/bin/sh
# Only IPv4 (could be easily IPv6 but need minfirewall / NEEDRESTRICT IPv6-compatible first)
rpkideny_file=/var/tmp/rpki_deny
cd /var/tmp
rm -f $rpkideny_file
GET http://antispam00.evolix.org/spam/rpki.cidr.md5 > rpki.cidr.md5
GET http://antispam00.evolix.org/spam/rpki.cidr > rpki.cidr
for i in 4134; do
grep "^$i," rpki.cidr | grep -v '::' >> $rpkideny_file
done
/sbin/iptables -F NEEDRESTRICT
for i in $(cat $rpkideny_file); do
BLOCK=$(echo $i | cut -d, -f2)
/sbin/iptables -I NEEDRESTRICT -s $BLOCK -j DROP
done

18
blacklist-asiapacific.sh Normal file
View file

@ -0,0 +1,18 @@
#!/bin/sh
# use it with /sbin/iptables -I INPUT -m set --match-set apnic-ipv4 src -j DROP
cd /var/tmp
rm -f $apnicdeny_file
GET http://antispam00.evolix.org/spam/apnic.cidr.md5 > apnic.cidr.md5
GET http://antispam00.evolix.org/spam/apnic.cidr > apnic.cidr
ipset destroy apnic-ipv4
ipset create apnic-ipv4 hash:net
for i in $(cat /var/tmp/apnic.cidr); do
BLOCK=$(echo $i | cut -d"|" -f2)
/sbin/ipset add apnic-ipv4 $BLOCK
done

View file

@ -29,7 +29,7 @@
# Description: Firewall designed for standalone server
### END INIT INFO
VERSION="23.07"
VERSION="24.07"
PROGNAME="minifirewall"
# shellcheck disable=SC2034
@ -111,6 +111,10 @@ STATE_FILE_DIFF='/var/run/minifirewall_state_diff'
ACTIVE_CONFIG='/var/run/minifirewall_active_config'
ACTIVE_CONFIG_DIFF="${ACTIVE_CONFIG}.diff"
SAFETY_LOCK='/var/run/minifirewall_safety.lock'
SAFETY_OUTPUT='/var/run/minifirewall_safety.out'
SAFETY_TIMER=30
LOGGER_BIN=$(command -v logger)
# No colors by default
@ -123,8 +127,10 @@ CYAN=''
WHITE=''
BOLD=''
RESET=''
# check if stdout is a terminal...
if [ -t 1 ]; then
INTERACTIVE=1
# see if it supports colors...
ncolors=$(tput colors)
@ -141,7 +147,10 @@ if [ -t 1 ]; then
BOLD=$(tput bold)
RESET='\e[m'
fi
else
INTERACTIVE=0
fi
readonly INTERACTIVE
## pseudo dry-run :
## Uncomment and call these functions instead of the real iptables and ip6tables commands
@ -155,6 +164,9 @@ fi
# }
## Beware that commands executed from included files are not modified by this trick.
is_interactive() {
test "${INTERACTIVE}" = "1"
}
remove_colors() {
sed -r 's/\x1B\[(;?[0-9]{1,3})+[mGK]//g'
}
@ -310,10 +322,10 @@ check_active_configuration() {
diff_bin=$(command -v diff)
if [ -z "${cmp_bin}" ]; then
printf "${YELLOW}Skipped active configuration check (Can't find cmp(1) command)${RESET}\n"
printf "${YELLOW}WARNING: Skipped active configuration check (Can't find cmp(1) command)${RESET}\n"
rc=1
elif [ -z "${diff_bin}" ]; then
printf "${YELLOW}Skipped active configuration check (Can't find diff(1) command)${RESET}\n"
printf "${YELLOW}WARNING: Skipped active configuration check (Can't find diff(1) command)${RESET}\n"
rc=1
else
rm -f "${ACTIVE_CONFIG_DIFF}"
@ -326,15 +338,15 @@ check_active_configuration() {
if [ ${cmp_rc} -eq 0 ]; then
# echo " config has not changed since latest start"
printf "${GREEN}Active configuration is up-to-date.${RESET}\n"
printf "${GREEN}OK: Active configuration is up-to-date.${RESET}\n"
rc=0
elif [ ${cmp_rc} -eq 1 ]; then
diff -u "${ACTIVE_CONFIG}" "${tmp_config_file}" > "${ACTIVE_CONFIG_DIFF}"
printf "${RED}Active configuration is not up-to-date (minifirewall not restarted after config change?), check %s${RESET}\n" "${ACTIVE_CONFIG_DIFF}"
printf "${RED}CRITICAL: Active configuration is not up-to-date (minifirewall not restarted after config change?), check %s${RESET}\n" "${ACTIVE_CONFIG_DIFF}"
rc=2
else
printf "${RED}Error while comparing rules:${RESET}\n"
printf "${RED}CRITICAL: Error while comparing rules:${RESET}\n"
printf "${cmp_result}\n"
rc=2
fi
@ -342,7 +354,7 @@ check_active_configuration() {
rm -f "${tmp_config_file}"
fi
else
printf "${YELLOW}Skipped active configuration check (missing file ${ACTIVE_CONFIG})${RESET}\n"
printf "${YELLOW}WARNING: Skipped active configuration check (missing file ${ACTIVE_CONFIG})${RESET}\n"
rc=1
fi
exit ${rc}
@ -543,6 +555,10 @@ start() {
${IPT6} -A LOG_ACCEPT -j ACCEPT
fi
if is_docker_enabled; then
${IPT} -N MINIFW-DOCKER-INPUT-MANUAL
fi
# Source additional rules and commands
# * from legacy configuration file (/etc/default/minifirewall)
# * from configuration directory (/etc/minifirewall.d/*)
@ -651,6 +667,10 @@ start() {
${IPT} -A MINIFW-DOCKER-PUB -j MINIFW-DOCKER-PRIVILEGED
${IPT} -A MINIFW-DOCKER-PUB -j RETURN
# Chain MINIFW-DOCKER-INPUT-MANUAL is created earlier, to allow usage in additionnal config/command files
${IPT} -A MINIFW-DOCKER-INPUT-MANUAL -j MINIFW-DOCKER-PUB
${IPT} -A MINIFW-DOCKER-INPUT-MANUAL -j RETURN
# Flush DOCKER-USER if exist, create it if absent
if chain_exists 'DOCKER-USER'; then
${IPT} -F DOCKER-USER
@ -658,8 +678,8 @@ start() {
${IPT} -N DOCKER-USER
fi;
# Pipe new connection through MINIFW-DOCKER-PUB
${IPT} -A DOCKER-USER -i ${INT} -m state --state NEW -j MINIFW-DOCKER-PUB
# Pipe new connection through MINIFW-DOCKER-INPUT-MANUAL
${IPT} -A DOCKER-USER -i ${INT} -m state --state NEW -j MINIFW-DOCKER-INPUT-MANUAL
${IPT} -A DOCKER-USER -j RETURN
fi
@ -806,12 +826,12 @@ start() {
if is_ipv6 ${IP}; then
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT6} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED -j ACCEPT
${IPT6} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT
fi
else
${IPT} -A INPUT -p tcp ! --syn --sport 53 --dport ${PORTSUSER} -s ${IP} -j ACCEPT
${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT} -A INPUT -p udp --sport 53 --dport ${PORTSUSER} -s ${IP} -m state --state ESTABLISHED -j ACCEPT
${IPT} -A OUTPUT -o ${INT} -p udp -d ${IP} --dport 53 --match state --state NEW -j ACCEPT
fi
done
@ -931,10 +951,10 @@ start() {
if [ -n "${server_ip}" ] && [ -n "${server_port}" ]; then
if is_ipv6 ${server_ip}; then
if is_ipv6_enabled; then
${IPT6} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT6} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED -j ACCEPT
fi
else
${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED,RELATED -j ACCEPT
${IPT} -A INPUT -p tcp --sport "${server_port}" --dport 1024:65535 -s "${server_ip}" -m state --state ESTABLISHED -j ACCEPT
fi
else
printf "${RED}ERROR: unrecognized syntax for BACKUPSERVERS '%s\`. Use space-separated IP:PORT tuples.${RESET}\n" "${server}" >&2
@ -978,9 +998,9 @@ start() {
${IPT6} -A OUTPUT -o ${INT} -p udp --dport 33434:33523 --match state --state NEW -j ACCEPT
fi
${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT
${IPT} -A OUTPUT -p udp --match state --state ESTABLISHED -j ACCEPT
if is_ipv6_enabled; then
${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED,RELATED -j ACCEPT
${IPT6} -A OUTPUT -p udp --match state --state ESTABLISHED -j ACCEPT
fi
${IPT} -A OUTPUT -p udp -j DROP
@ -1050,6 +1070,8 @@ stop() {
${IPT} -F DOCKER-USER
${IPT} -A DOCKER-USER -j RETURN
${IPT} -F MINIFW-DOCKER-INPUT-MANUAL
${IPT} -X MINIFW-DOCKER-INPUT-MANUAL
${IPT} -F MINIFW-DOCKER-PUB
${IPT} -X MINIFW-DOCKER-PUB
${IPT} -F MINIFW-DOCKER-PRIVILEGED
@ -1143,6 +1165,67 @@ reset() {
syslog_info "reset"
printf "${GREEN}${BOLD}${PROGNAME} reset${RESET}\n"
}
safety_timer() {
if [ "${SAFETY_TIMER}" -le "0" ] || [ "${SAFETY_TIMER}" -gt "3600" ]; then
syslog_info "safety timer value '${SAFETY_TIMER}' is out of range (1 < 3600), reverted to default value of '30'."
SAFETY_TIMER=30
readonly SAFETY_TIMER
fi
echo "${SAFETY_TIMER}"
}
stop_if_locked() {
count=0
while [ "${count}" -lt "$(safety_timer)" ] && [ -f "${SAFETY_LOCK}" ]; do
count=$(( count + 1 ))
sleep 1
done
if [ -f "${SAFETY_LOCK}" ]; then
syslog_error "safety lock is still here after $(safety_timer) seconds, we need to stop"
stop
syslog_info "remove safety lock"
rm -f "${SAFETY_LOCK}"
else
syslog_info "safety lock is not there anymore, life goes on"
fi
}
safe_start() {
# start the firewall
start
# create the lock file
syslog_info "add safety lock"
touch "${SAFETY_LOCK}"
# run the special background command
nohup "${0}" stop-if-locked > "${SAFETY_OUTPUT}" 2>&1 &
if is_interactive; then
syslog_info "safe-restart in interactive mode ; if safety lock (${SAFETY_LOCK}) is not removed in the next $(safety_timer) seconds, minifirewall will be stopped."
# Ask for input
confirm_default="I'm locked out, please stop the firewall"
# printf "If the restart has locked you out you might see this but you shouldn't be able to type anything.\n"
printf "Minifirewall will be stopped in $(safety_timer) seconds if you do nothing.\n"
printf "Remove \`${SAFETY_LOCK}' or type anything to keep minifirewall started: "
read -r confirm
if [ ! -f "${SAFETY_LOCK}" ]; then
printf "${YELLOW}Safety lock is not there anymore.\nYou've probably been rescued by the safety checks.\n${BOLD}Minifirewall is probably stopped.${RESET}\n"
elif [ "${confirm}" != "${confirm_default}" ]; then
rm -f "${SAFETY_LOCK}" && printf "${GREEN}OK. Safety lock is removed.${RESET}\n"
fi
else
syslog_info "safe-restart in non-interactive mode ; if safety lock (${SAFETY_LOCK}) is not removed in the next $(safety_timer) seconds, minifirewall will be stopped."
fi
}
show_version() {
cat <<END
${PROGNAME} version ${VERSION}
@ -1169,8 +1252,10 @@ Usage: ${PROGNAME} [COMMAND]
Commands
start Start minifirewall
safe-start Start minifirewall, with baground safety checks
stop Stop minifirewall
restart Stop then start minifirewall
safe-restart Restart minifirewall, with background safety checks
status Print minifirewall status
reset Reset iptables tables
check-active-config Check if active config is up-to-date with stored config
@ -1187,6 +1272,13 @@ case "${1:-''}" in
start
;;
safe-start)
source_configuration
check_unpersisted_state
safe_start
;;
stop)
source_configuration
check_unpersisted_state
@ -1216,6 +1308,20 @@ case "${1:-''}" in
start
;;
safe-restart)
source_configuration
check_unpersisted_state
stop
safe_start
;;
stop-if-locked)
source_configuration
stop_if_locked
;;
check-active-config)
check_active_configuration
;;

View file

@ -1,5 +1,5 @@
# Configuration for minifirewall : https://gitea.evolix.org/evolix/minifirewall
# Version 23.07
# Version 24.11
# shellcheck shell=sh disable=SC2034
# Main interface
@ -23,8 +23,7 @@ DOCKER='off'
INTLAN='192.0.2.1/32 2001:db8::1/128'
# Trusted IP addresses for private and semi-public services
# TODO: add all our IPv6 adresses
TRUSTEDIPS='31.170.9.129 2a01:9500:37:129::/64 31.170.8.4 2a01:9500::fada/128 82.65.34.85 54.37.106.210 51.210.84.146'
TRUSTEDIPS='31.170.9.129 2a01:9500:37:129::/64 31.170.8.4 2a01:9500::fada 82.65.34.85 2a01:e0a:571:2a10::1 46.231.240.96 2a0c:e303:0:6000::/57 54.37.106.210 2001:41d0:8:8b70::210 51.210.84.146 2001:41d0:8:8b70::146'
# Privilegied IP addresses for semi-public services
# (no need to add again TRUSTEDIPS)
@ -34,7 +33,7 @@ PRIVILEGIEDIPS=''
# Local services IP restrictions
#######################################
# Protected services
# Protected services (protected by NEEDRESTRICT chain, to customize in your own way)
# (add also in Public services if needed)
SERVICESTCP1p='22222'
SERVICESUDP1p=''
@ -43,11 +42,11 @@ SERVICESUDP1p=''
SERVICESTCP1='22222'
SERVICESUDP1=''
# Semi-public services (IPv4)
# Semi-public services (for IPv4/IPv6 from PRIVILEGIEDIPS *and* TRUSTEDIPS)
SERVICESTCP2='22'
SERVICESUDP2=''
# Private services (IPv4)
# Private services (for IPv4/IPv6 from TRUSTEDIPS only)
SERVICESTCP3='5666'
SERVICESUDP3=''
@ -102,7 +101,7 @@ BACKUPSERVERS=''
#
# Within included files, you can use those helper functions :
# * is_ipv6_enabled: returns true if IPv6 is enabled, or false
# * is_docker_enabled: returns true if Docker mode is eabled, or false
# * is_docker_enabled: returns true if Docker mode is enabled, or false
# * is_proxy_enabled: returns true if Proxy mode is enabled , or false

22
rpki.sh Normal file
View file

@ -0,0 +1,22 @@
#!/bin/sh
umask 022
tmp_rpki_file="/var/tmp/tmp_rpki.cidr"
rpki_file="/var/tmp/rpki.cidr"
rm -f $rpki_file
YEAR_TODAY=$( date +%Y )
MONTH_TODAY=$( date +%m )
DAY_TODAY=$( date +%d )
wget -q -O- https://ftp.ripe.net/ripe/rpki/ripencc.tal/${YEAR_TODAY}/${MONTH_TODAY}/${DAY_TODAY}/roas.csv.xz | unxz | grep ^rsync > $tmp_rpki_file
wget -q -O- https://ftp.ripe.net/ripe/rpki/arin.tal/${YEAR_TODAY}/${MONTH_TODAY}/${DAY_TODAY}/roas.csv.xz | unxz | grep ^rsync >> $tmp_rpki_file
wget -q -O- https://ftp.ripe.net/ripe/rpki/afrinic.tal/${YEAR_TODAY}/${MONTH_TODAY}/${DAY_TODAY}/roas.csv.xz | unxz | grep ^rsync >> $tmp_rpki_file
wget -q -O- https://ftp.ripe.net/ripe/rpki/lacnic.tal/${YEAR_TODAY}/${MONTH_TODAY}/${DAY_TODAY}/roas.csv.xz | unxz | grep ^rsync >> $tmp_rpki_file
cat $tmp_rpki_file | cut -d, -f2,3 | sed 's/^AS//' | sort > $rpki_file
md5sum $rpki_file > /var/www/spam/rpki.cidr.md5
mv $rpki_file /var/www/spam/