Skip to content

Commit 68de75a

Browse files
committed
fix: more ansible fixes for redis/mongo
1 parent 3a80436 commit 68de75a

File tree

7 files changed

+606
-29
lines changed

7 files changed

+606
-29
lines changed

.env.defaults

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
MONGO_BACKUP_BUCKET=forwardemail-backups
2+
REDIS_BACKUP_BUCKET=forwardemail-backups
3+
REDIS_DATA_DIR=/var/lib/redis
4+
15
###################################
26
## ignored self test domains ##
37
## (see `helpers/on-data-mx.js`) ##
@@ -262,7 +266,10 @@ EMAILS_MONGO_URI="mongodb://{{EMAILS_MONGO_HOST}}:{{EMAILS_MONGO_PORT}}/{{EMAILS
262266
REDIS_TLS=false
263267
REDIS_USERNAME=
264268
REDIS_PORT=6379
269+
REDIS_TLS_PORT=6380
265270
REDIS_HOST=localhost
271+
# Generate a 64-character random password (Redis can handle long passwords)
272+
# openssl rand -base64 48
266273
REDIS_PASSWORD=
267274
WEB_REDIS_TLS={{REDIS_TLS}}
268275
WEB_REDIS_USERNAME={{REDIS_USERNAME}}

.env.schema

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
# MongoDB Configuration
2+
MONGO_HOST=
3+
MONGO_BACKUP_BUCKET=forwardemail-backups
4+
5+
# Redis Configuration
6+
REDIS_HOST=
7+
REDIS_PASSWORD=
8+
REDIS_BACKUP_BUCKET=forwardemail-backups
9+
REDIS_DATA_DIR=/var/lib/redis
10+
11+
# SSL/TLS Configuration (shared by both mongo/redis and inherited by others)
12+
SSL_CERT_PATH=
13+
SSL_KEY_PATH=
14+
SSL_CA_PATH=
15+
16+
# Generate a 32-character random password
17+
# openssl rand -base64 32
18+
BACKUP_SECRET=
19+
120
###################################
221
## ignored self test domains ##
322
## (see `helpers/on-data-mx.js`) ##
@@ -263,6 +282,7 @@ EMAILS_MONGO_URI=
263282
REDIS_TLS=
264283
REDIS_USERNAME=
265284
REDIS_PORT=
285+
REDIS_TLS_PORT=
266286
REDIS_HOST=
267287
REDIS_PASSWORD=
268288
WEB_REDIS_TLS=
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
#!/bin/bash
2+
SCRIPTNAME="Portscan Protection"
3+
VERSION="26-06-2023"
4+
SCRIPTLOCATION="/usr/local/sbin/portscan-protection.sh"
5+
WHITELISTLOCATION="/usr/local/sbin/portscan-protection-white.list"
6+
CRONLOCATION="/etc/cron.d/portscan-protection"
7+
GITHUBRAW="https://raw.githubusercontent.com/forwardemail/portscan-protection/master/portscan-protection.sh"
8+
AUTOUPDATE="YES" # Edit this variable to "NO" if you don't want to auto update this script (NOT RECOMMENDED)
9+
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
10+
11+
#
12+
# Define some functions
13+
#
14+
15+
IPSETCOMMANDCHECK()
16+
{
17+
# Check the ipset command
18+
! command -v ipset > /dev/null && printf "\nipset command ${RED}not found${NC}.\n" && exit 6 || printf "ipset command found. ${GR}OK.${NC}\n"
19+
}
20+
21+
22+
IPTABLECOMMANDCHECK()
23+
{
24+
# Check the iptables command
25+
! command -v iptables > /dev/null && printf "iptables command ${RED}not found${NC}.\n" && exit 7 || printf "iptables command found. ${GR}OK.${NC}\n"
26+
}
27+
28+
29+
SETCRONTAB()
30+
{
31+
[ ! -f "$CRONLOCATION" ] || ! grep -q "reboot root sleep" "$CRONLOCATION" && printf "# $SCRIPTNAME installed at $(date)\n@reboot root sleep 30 && $SCRIPTLOCATION --cron\n\n" > "$CRONLOCATION" && printf "Crontab entry has been set. ${GR}OK.${NC}\n" || printf "Crontab entry ${GR}already set.${NC}\n"
32+
}
33+
34+
35+
WHITELIST()
36+
{
37+
[ ! -f "$WHITELISTLOCATION" ] && printf "# This file is part of $SCRIPTNAME\n# Add one IP per line to this file. These IP addresses will be never blocked. Note: Only IPv4 addresses are supported.\n# More info on GitHub: https://github.com/Feriman22/portscan-protection\n# If you found it useful, please donate via PayPal: https://paypal.me/BajzaFerenc\n\n# Thank you!\n\n127.0.0.1" > $WHITELISTLOCATION
38+
for i in nano vi vim; do
39+
if command -v $i > /dev/null; then
40+
$i "$WHITELISTLOCATION"
41+
"$SCRIPTLOCATION" --cron
42+
printf "Whitelist has been activated if the file has been modified.\n" ; FOUND="1"
43+
break
44+
fi
45+
done
46+
[ "$FOUND" != "1" ] && echo "nano, vi or vim is not found. Edit manually the whitelist: $WHITELISTLOCATION"
47+
}
48+
49+
50+
UPDATE()
51+
{
52+
# Getting info about the latest GitHub version
53+
NEW=$(curl -s "$GITHUBRAW" | awk -F'"' '/^VERSION/ {print $2}')
54+
55+
# Compare the installed and the GitHub stored version - Only internal, not available by any argument
56+
if [[ "$1" == "ONLYCHECK" ]] && [[ "$NEW" != "$VERSION" ]]; then
57+
[ "$1" != '--cron' ] && printf "New version ${YL}available!${NC}\n"
58+
else
59+
[[ "$1" == "ONLYCHECK" ]] && [ "$1" != '--cron' ] && printf "The downloaded $SCRIPTNAME is ${GR}up to date.${NC}\n\n"
60+
fi
61+
62+
# Check the current installation
63+
if [[ "$1" != "ONLYCHECK" ]] && [ -f "$CRONLOCATION" ] && [ -x "$SCRIPTLOCATION" ]; then
64+
65+
# Check the GitHub - Is it available? - Exit if not
66+
if [[ ! "$NEW" ]]; then
67+
[ "$1" != '--cron' ] && printf "GitHub is ${RED}not available now.${NC} Try again later.\n"
68+
exit 8
69+
fi
70+
71+
# Compare the installed and the GitHub stored version
72+
if [[ "$NEW" != "$VERSION" ]]; then
73+
curl -s -o "$SCRIPTLOCATION" "$GITHUBRAW"
74+
SETCRONTAB
75+
[ "$1" != '--cron' ] && printf "Script has been ${GR}updated.${NC}\n"
76+
else
77+
[ "$1" != '--cron' ] && printf "The installed $SCRIPTNAME is ${GR}up to date.${NC}\n\n"
78+
fi
79+
else
80+
[[ "$1" != "ONLYCHECK" ]] && [ "$1" != '--cron' ] && printf "Script ${RED}not installed.${NC} Install first then you can update it.\n"
81+
fi
82+
}
83+
84+
85+
if [ "$1" != '--cron' ]; then
86+
# Coloring
87+
RED='\033[0;31m' # Red Color
88+
GR='\033[0;32m' # Green Color
89+
YL='\033[0;33m' # Yellow Color
90+
NC='\033[0m' # No Color
91+
92+
printf "\n$SCRIPTNAME\n"
93+
echo "Author: Feriman"
94+
echo "URL: https://github.com/Feriman22/portscan-protection"
95+
echo "Open GitHub page to read the manual and check new releases"
96+
echo "Current version: $VERSION"
97+
UPDATE ONLYCHECK # Check new version
98+
printf "${GR}If you found it useful${NC}, please donate via PayPal: https://paypal.me/BajzaFerenc\n\n"
99+
fi
100+
101+
# Check the root permission
102+
[ ! "$(id -u)" = 0 ] && printf "${RED}Run as root!${NC}\n" && exit 5
103+
104+
# Check curl, ipset, iptables commands
105+
for i in curl ipset iptables; do ! command -v ipset > /dev/null && echo "$i command ${RED}not found${NC}" && NOT_FOUND="1"; done
106+
[ "$NOT_FOUND" == "1" ] && exit 10
107+
108+
# Define ipset and iptable rules - Used at magic and uninstall part
109+
IPSET1='port_scanners hash:ip family inet hashsize 32768 maxelem 65536 timeout 600'
110+
IPSET2='scanned_ports hash:ip,port family inet hashsize 32768 maxelem 65536 timeout 60'
111+
IPTABLE1='INPUT -m state --state INVALID -j DROP'
112+
IPTABLE2='INPUT -m state --state NEW -m set ! --match-set scanned_ports src,dst -m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-mode srcip --hashlimit-name portscan --hashlimit-htable-expire 10000 -j SET --add-set port_scanners src --exist'
113+
IPTABLE3='INPUT -m state --state NEW -m set --match-set port_scanners src -j DROP'
114+
IPTABLE4='INPUT -m state --state NEW -j SET --add-set scanned_ports src,dst'
115+
116+
# Enter in this section only if run by cron - It will do the magic
117+
if [ "$1" == '--cron' ]; then
118+
119+
# Add Whitelist IPs if any
120+
if [ -f $WHITELISTLOCATION ]; then
121+
while read WHILELISTIP; do
122+
# Validate IP address
123+
if [[ "$WHILELISTIP" =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$ ]] && [ $(iptables -S | grep -cF -- "-A INPUT -s $WHILELISTIP/32 -j ACCEPT") -lt 1 ]; then
124+
iptables -I INPUT -s $WHILELISTIP -j ACCEPT
125+
fi
126+
done < <(grep -v "^#\|^$" $WHITELISTLOCATION)
127+
fi
128+
129+
ipset list | grep -q port_scanners || ipset create $IPSET1
130+
ipset list | grep -q scanned_ports || ipset create $IPSET2
131+
iptables -S | grep -qF -- "-A $IPTABLE1" || iptables -A $IPTABLE1
132+
iptables -S | grep -qF -- "-A $IPTABLE2" || iptables -A $IPTABLE2
133+
iptables -S | grep -qF -- "-A $IPTABLE3" || iptables -A $IPTABLE3
134+
iptables -S | grep -qF -- "-A $IPTABLE4" || iptables -A $IPTABLE4
135+
136+
# Auto update if not disabled
137+
[ "$AUTOUPDATE" == "YES" ] && UPDATE --cron
138+
139+
# Exit, because it run by cron
140+
exit 0
141+
fi
142+
143+
# Call the menu
144+
if [ "$1" == "-i" ] || [ "$1" == "-u" ] || [ "$1" == "-v" ] || [ "$1" == "--install" ] || [ "$1" == "--uninstall" ] || [ "$1" == "--verify" ] || [ "$1" == "-up" ] || [ "$1" == "--update" ]; then
145+
OPT="$1" && OPTL="$1" && ARG="YES"
146+
else
147+
PS3='Please enter your choice: '
148+
[ -f "$SCRIPTLOCATION" ] && options=("Verify" "Edit Whitelist" "Update from GitHub" "Uninstall" "Quit")
149+
[ ! -f "$SCRIPTLOCATION" ] && options=("Install" "Verify" "Quit")
150+
select opt in "${options[@]}"
151+
do
152+
case $opt in
153+
"Install")
154+
OPT='-i' && OPTL='--install' && break
155+
;;
156+
"Uninstall")
157+
OPT='-u' && OPTL='--uninstall' && break
158+
;;
159+
"Edit Whitelist")
160+
WHITELIST ; break
161+
;;
162+
"Verify")
163+
OPT='-v' && OPTL='--verify' && break
164+
;;
165+
"Update from GitHub")
166+
UPDATE && break
167+
;;
168+
"Quit")
169+
break
170+
;;
171+
*) echo "Invalid option $REPLY";;
172+
esac
173+
done
174+
fi
175+
176+
##
177+
########### Menu: Install ###########
178+
##
179+
180+
if [ "$OPT" == '-i' ] || [ "$OPTL" == '--install' ]; then
181+
182+
#
183+
### Start Installation ###
184+
#
185+
186+
# Start count the time of install process
187+
SECONDS=0
188+
189+
IPSETCOMMANDCHECK
190+
191+
IPTABLECOMMANDCHECK
192+
193+
# Set crontab rule if it does not already exist
194+
SETCRONTAB
195+
196+
# Copy the script to $SCRIPTLOCATION and add execute permission
197+
INSTALLERLOCATION=$(realpath $0)
198+
if [ "$INSTALLERLOCATION" != "$SCRIPTLOCATION" ]; then
199+
curl -s -o "$SCRIPTLOCATION" "$GITHUBRAW" && chmod +x "$SCRIPTLOCATION" && printf "$SCRIPTNAME has been copied in $SCRIPTLOCATION ${GR}OK.${NC}\n"
200+
else
201+
printf "$SCRIPTNAME already copied to destination. Nothing to do. ${GR}OK.${NC}\n"
202+
fi
203+
204+
# First "cron like" run to activate the iptable rules
205+
"$SCRIPTLOCATION" --cron && printf "iptable rules have been activated. You are protected! ${GR}OK.${NC}\n"
206+
207+
# Finish
208+
printf "\n${GR}Note:${NC} If you want to Edit Whitelist, or Verify the install, just run the below command:\nsudo $SCRIPTLOCATION\n\n"
209+
printf "${GR}Done.${NC} The install was $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec. That was so quick, wasn't?\n"
210+
fi
211+
212+
213+
##
214+
########### Menu: Uninstall ###########
215+
##
216+
217+
if [ "$OPT" == '-u' ] || [ "$OPTL" == '--uninstall' ]; then
218+
if [ "$ARG" != 'YES' ]; then
219+
loop=true;
220+
while $loop; do
221+
printf "${RED}UNINSTALL${NC} $SCRIPTNAME on $(hostname).\n"
222+
read -p "Are you sure? [Y/n]: " var1
223+
loop=false;
224+
if [ "$var1" == 'Y' ] || [ "$var1" == 'y' ]; then
225+
printf "Okay! You have 5 sec until starting the ${RED}UNINSTALL${NC} process on $(hostname). Press Ctrl + C to exit.\n"
226+
for i in {5..1}; do echo $i && sleep 1; done
227+
elif [ "$var1" == 'N' ] || [ "$var1" == 'n' ]; then
228+
echo "Okay, exit."
229+
exit 9
230+
else
231+
echo "Enter a valid response Y or n";
232+
loop=true;
233+
fi
234+
done
235+
fi
236+
237+
#
238+
### Starting Uninstall ###
239+
#
240+
241+
# Remove crontab file
242+
if [ -f "$CRONLOCATION" ]; then
243+
rm -r "$CRONLOCATION"
244+
printf "\nCrontab file has been removed. ${GR}OK.${NC}\n"
245+
else
246+
printf "\nCrontab file not found. ${GR}OK.${NC}\n"
247+
fi
248+
249+
# Remove the script
250+
[ -f "$SCRIPTLOCATION" ] && rm -f "$SCRIPTLOCATION" && printf "$SCRIPTNAME has been removed. ${GR}OK.${NC}\n" || printf "Script not found. ${GR}OK.${NC}\n"
251+
252+
# Remove iptable rules
253+
N=1
254+
for IPTABLERULE in "$IPTABLE1" "$IPTABLE2" "$IPTABLE3" "$IPTABLE4"; do
255+
if iptables -S | grep -qF -- "-A $IPTABLERULE"; then
256+
iptables -D $IPTABLERULE
257+
printf "#$N iptable rule has been removed. ${GR}OK.${NC}\n"
258+
else
259+
printf "#$N iptable rule not found. ${GR}OK.${NC}"
260+
fi
261+
((N++))
262+
done
263+
264+
# Remove Whitelist rules
265+
if [ -f $WHITELISTLOCATION ]; then
266+
while read WHILELISTIP; do
267+
# Validate IP address
268+
if [[ "$WHILELISTIP" =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$ ]]; then
269+
iptables -D INPUT -s $WHILELISTIP -j ACCEPT
270+
fi
271+
done < <(grep -v "^#\|^$" $WHITELISTLOCATION)
272+
printf "Whitelist removed from iptables if any. ${GR}OK.${NC}"
273+
fi
274+
275+
# Remove Whitelist
276+
[ -f "$WHITELISTLOCATION" ] && rm -f "$WHITELISTLOCATION" && printf "Whitelist has been removed. ${GR}OK.${NC}\n" || printf "Whitelist not found. ${GR}OK.${NC}\n"
277+
278+
# Remove ipset rules
279+
for IPSETRULE in scanned_ports port_scanners; do
280+
if ipset list | grep -q "$IPSETRULE"; then
281+
sleep 1
282+
ipset destroy $IPSETRULE
283+
printf "$IPSETRULE ipset rule has been removed. ${GR}OK.${NC}\n"
284+
else
285+
printf "$IPSETRULE ipset rule not found. ${GR}OK.${NC}\n"
286+
fi
287+
done
288+
289+
printf "\nIf the $SCRIPTNAME removed accidently, run this below command to install it again:\n"
290+
printf "curl -s $GITHUBRAW | sudo bash /dev/stdin -i\n"
291+
fi
292+
293+
##
294+
########### Menu: Verify ###########
295+
##
296+
297+
if [ "$OPT" == '-v' ] || [ "$OPTL" == '--verify' ]; then
298+
299+
# Crontab verify
300+
[ ! -f "$CRONLOCATION" ] && printf "\nCrontab entry ${RED}not found.${NC}\n" || printf "\nCrontab entry found. ${GR}OK.${NC}\n"
301+
302+
# Verify script location
303+
if [ -f "$SCRIPTLOCATION" ]; then
304+
printf "Script found. ${GR}OK.${NC}\n"
305+
306+
# Verify execute permission
307+
[ -x "$SCRIPTLOCATION" ] && printf "The script is executable. ${GR}OK.${NC}\n" || printf "The execute permission is ${RED}missing.${NC} Fix it by run: chmod +x $SCRIPTLOCATION\n"
308+
309+
else
310+
printf "Script ${RED}not found.${NC}\n"
311+
fi
312+
313+
IPSETCOMMANDCHECK
314+
315+
IPTABLECOMMANDCHECK
316+
317+
iptables -S | grep -q port_scanners && iptables -S | grep -q scanned_ports && printf "iptables rules have been configured. You are protected! ${GR}OK.${NC}\n" || printf "iptables rules are ${RED}not configured!${NC}\n"
318+
319+
if [ -f $WHITELISTLOCATION ]; then
320+
while read WHILELISTIP; do
321+
# Validate IP address
322+
if [[ ! "$WHILELISTIP" =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$ ]]; then
323+
printf "$WHILELISTIP is ${RED}not valid${NC} IPv4 address in the Whitelist and it will be ignored. May you have to fix it by choose Edit Whitelist from the menu.\n"
324+
fi
325+
done < <(grep -v "^#\|^$" $WHITELISTLOCATION)
326+
fi
327+
fi
328+
329+
330+
##
331+
########### Menu: Update ###########
332+
##
333+
334+
[ "$OPT" == '-up' ] || [ "$OPTL" == '--update' ] && UPDATE

0 commit comments

Comments
 (0)