-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathset_external.sh
323 lines (254 loc) · 12 KB
/
set_external.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#!/bin/bash
# Define color codes for pretty output
GREEN="\033[0;32m"
RED="\033[0;31m"
YELLOW="\033[1;33m"
TEXTRESET="\033[0m"
clear
# Ensure nmcli is installed
if ! command -v nmcli &>/dev/null; then
echo -e "${RED}nmcli is not installed. Please install it and try again.${TEXTRESET}"
exit 1
fi
# Ensure nftables is installed and running
if ! command -v nft &>/dev/null; then
echo -e "${RED}nftables is not installed. Please install it and try again.${TEXTRESET}"
exit 1
fi
if ! systemctl is-active --quiet nftables; then
echo -e "${RED}nftables is not running. Please start it and try again.${TEXTRESET}"
exit 1
fi
# Get all connections managed by NetworkManager
connections=$(nmcli -t -f NAME,DEVICE,TYPE connection show)
# Display all interfaces that will be checked
echo -e "${YELLOW}Checking the following network interfaces for autoconnect settings:${TEXTRESET}"
while IFS=: read -r name device type; do
# Only show valid ethernet or wifi connections
if [ "$type" == "802-3-ethernet" ] || [ "$type" == "wifi" ]; then
echo -e "${YELLOW}- $device ($name): Type $type${TEXTRESET}"
fi
done <<<"$connections"
# Check and modify autoconnect settings
echo -e "\n${YELLOW}Modifying interfaces that are not set to autoconnect...${TEXTRESET}"
while IFS=: read -r name device type; do
# Process valid ethernet or wifi connections
if [ "$type" == "802-3-ethernet" ] || [ "$type" == "wifi" ]; then
# Check if the connection is set to autoconnect
autoconnect=$(nmcli -g connection.autoconnect connection show "$name")
if [ "$autoconnect" != "yes" ]; then
echo -e "${RED}Connection $name (Device: $device) is not set to autoconnect. Enabling autoconnect...${TEXTRESET}"
nmcli connection modify "$name" connection.autoconnect yes
if [ $? -eq 0 ]; then
echo -e "${GREEN}Autoconnect enabled for $name (Device: $device).${TEXTRESET}"
else
echo -e "${RED}Failed to enable autoconnect for $name (Device: $device).${TEXTRESET}"
fi
else
echo -e "${GREEN}Connection $name (Device: $device) is already set to autoconnect.${TEXTRESET}"
fi
fi
done <<<"$connections"
echo -e "${GREEN}Completed checking and updating autoconnect settings.${TEXTRESET}"
# Get currently connected interfaces
existing_connections=$(nmcli -t -f DEVICE,STATE dev status | grep ":connected" | cut -d: -f1)
echo -e "${YELLOW}Existing connected interfaces:${TEXTRESET}"
echo "$existing_connections"
echo -e "${YELLOW}Please plug in your Internet connection into the firewall. It should be in a separate subnet.${TEXTRESET}"
echo -e "${YELLOW}Waiting for a new interface to come up...${TEXTRESET}"
# Monitor for a new connection
while true; do
# Get current connected devices
current_connections=$(nmcli -t -f DEVICE,STATE dev status | grep ":connected" | cut -d: -f1)
# Find the new connection, excluding 'lo'
new_connection=$(comm -13 <(echo "$existing_connections" | sort) <(echo "$current_connections" | sort) | grep -v "^lo$")
if [ -n "$new_connection" ]; then
echo -e "${GREEN}Detected a new connection: $new_connection${TEXTRESET}"
# Get the current profile name associated with the new connection
current_profile=$(nmcli -t -f NAME,DEVICE connection show --active | grep ":${new_connection}$" | cut -d: -f1)
if [ -n "$current_profile" ]; then
# Update the connection profile name to include '-outside'
new_profile_name="${new_connection}-outside"
echo -e "${YELLOW}Updating connection profile name to: $new_profile_name${TEXTRESET}"
nmcli connection modify "$current_profile" connection.id "$new_profile_name"
nmcli connection reload
else
echo -e "${RED}Error: Could not find an active profile for $new_connection.${TEXTRESET}"
fi
break
fi
sleep 0.5 # Check every 0.5 seconds
done
# Function to find the outside interface
find_outside_interface() {
# Find the interface with a connection ending in -outside
outside_interface=$(nmcli device status | awk '/-outside/ {print $1}')
if [ -z "$outside_interface" ]; then
echo -e "${RED}Error: No interface with a connection ending in '-outside' found.${TEXTRESET}"
exit 1
fi
echo "$outside_interface"
}
##Load nftables with confguration and install threat lists
# Define variables for threat list management
THREAT_LISTS=(
"https://iplists.firehol.org/files/firehol_level1.netset"
"https://www.abuseipdb.com/blacklist.csv"
"https://rules.emergingthreats.net/blockrules/compromised-ips.txt"
)
BLOCK_SET="threat_block"
TMP_DIR="/etc/nftables"
TMP_FILE="$TMP_DIR/threat_list.txt"
# Function to find the network interface based on connection name ending
find_interface() {
local suffix="$1"
nmcli -t -f DEVICE,CONNECTION device status | awk -F: -v suffix="$suffix" '$2 ~ suffix {print $1}'
}
# Function to find sub-interfaces based on main interface
find_sub_interfaces() {
local main_interface="$1"
nmcli -t -f DEVICE device status | grep -E "^${main_interface}\.[0-9]+" | awk '{print $1}'
}
# Setup the FW: Determine inside and outside interfaces
echo -e "${YELLOW}Determining network interfaces...${RESET}" | tee >(logger)
INSIDE_INTERFACE=$(find_interface "-inside")
OUTSIDE_INTERFACE=$(find_interface "-outside")
echo -e "${GREEN}Inside interface: $INSIDE_INTERFACE${RESET}" | tee >(logger)
echo -e "${GREEN}Outside interface: $OUTSIDE_INTERFACE${RESET}" | tee >(logger)
if [[ -z "$INSIDE_INTERFACE" || -z "$OUTSIDE_INTERFACE" ]]; then
echo -e "${RED}Error: Could not determine one or both interfaces. Please check your connection names.${RESET}" | tee >(logger)
exit 1
fi
# Find sub-interfaces for the inside interface
SUB_INTERFACES=$(find_sub_interfaces "$INSIDE_INTERFACE")
# Enable IP forwarding
echo -e "${YELLOW}Enabling IP forwarding...${RESET}" | tee >(logger)
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Apply nftables ruleset
echo -e "${YELLOW}Applying nftables ruleset...${RESET}" | tee >(logger)
# Create and configure the inet filter table if not exists
sudo nft add table inet filter 2>/dev/null
# Ensure the input chain policy is set to drop
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; } 2>/dev/null
# Allow all traffic on the loopback interface
sudo nft add rule inet filter input iif lo accept
# Allow established and related connections on the input chain
sudo nft add rule inet filter input ct state established,related accept
# Allow inbound traffic on the inside interface(s)
sudo nft add rule inet filter input iif "$INSIDE_INTERFACE" accept
for sub_interface in $SUB_INTERFACES; do
echo -e "${YELLOW}Allowing inbound traffic for sub-interface: $sub_interface${RESET}" | tee >(logger)
sudo nft add rule inet filter input iif "$sub_interface" accept
done
# Allow SSH on the outside interface
sudo nft add rule inet filter input iif "$OUTSIDE_INTERFACE" tcp dport 22 accept
# Create and configure the forward chain with drop policy
sudo nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; } 2>/dev/null
# Allow established and related connections on the forward chain
sudo nft add rule inet filter forward ct state established,related accept
# Allow forwarding between inside interface and its sub-interfaces
sudo nft add rule inet filter forward iif "$INSIDE_INTERFACE" oif "$INSIDE_INTERFACE" accept
for sub_interface in $SUB_INTERFACES; do
sudo nft add rule inet filter forward iif "$INSIDE_INTERFACE" oif "$sub_interface" accept
sudo nft add rule inet filter forward iif "$sub_interface" oif "$INSIDE_INTERFACE" accept
sudo nft add rule inet filter forward iif "$sub_interface" oif "$sub_interface" accept
done
# Allow forwarding from inside to outside
sudo nft add rule inet filter forward iif "$INSIDE_INTERFACE" oif "$OUTSIDE_INTERFACE" accept
for sub_interface in $SUB_INTERFACES; do
sudo nft add rule inet filter forward iif "$sub_interface" oif "$OUTSIDE_INTERFACE" accept
done
# Create and configure the inet nat table
sudo nft add table ip nat 2>/dev/null
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; } 2>/dev/null
sudo nft add rule ip nat postrouting oif "$OUTSIDE_INTERFACE" masquerade
# Log and drop unsolicited incoming traffic on the outside interface
echo -e "${YELLOW}Logging and blocking unsolicited incoming traffic on the outside interface...${RESET}" | tee >(logger)
sudo nft add rule inet filter input iif "$OUTSIDE_INTERFACE" log prefix "\"Blocked: \"" drop
# Create a named set for threat blocking
sudo nft add set inet filter $BLOCK_SET { type ipv4_addr\; flags timeout\; } 2>/dev/null
# Add a rule to drop traffic from IPs in the threat list
sudo nft add rule inet filter input ip saddr @$BLOCK_SET drop
echo -e "${GREEN}nftables ruleset applied successfully.${RESET}" | tee >(logger)
# Save the current ruleset
echo -e "${YELLOW}Saving the current nftables ruleset...${RESET}" | tee >(logger)
sudo nft list ruleset >/etc/sysconfig/nftables.conf
# Enable and start nftables service to ensure configuration is loaded on boot
echo -e "${YELLOW}Enabling nftables service...${RESET}" | tee >(logger)
sudo systemctl enable nftables
sudo systemctl start nftables
echo -e "nftables ruleset applied and saved successfully." | tee >(logger)
echo -e "The Next step may take a minute we are downloading updates, be patient."
echo -e "Creating and downloading threat lists for nftables"
# Create the threat list update script
cat <<'EOF' >/usr/local/bin/update_nft_threatlist.sh
#!/bin/bash
# Define variables
THREAT_LISTS=(
"https://iplists.firehol.org/files/firehol_level1.netset"
"https://www.abuseipdb.com/blacklist.csv"
"https://rules.emergingthreats.net/blockrules/compromised-ips.txt"
)
BLOCK_SET="threat_block"
TMP_DIR="/etc/nftables"
TMP_FILE="$TMP_DIR/threat_list.txt"
# Ensure the directory exists
mkdir -p $TMP_DIR
# Clear the temporary file
> $TMP_FILE
# Download and combine threat lists
for LIST_URL in "${THREAT_LISTS[@]}"; do
echo "Downloading $LIST_URL..." | tee >(logger)
curl -s $LIST_URL >> $TMP_FILE
done
# Extract only valid IP addresses
grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' $TMP_FILE | sort -u > $TMP_FILE.cleaned
# Create or update the named set in nftables
sudo nft add table inet filter 2>/dev/null
sudo nft add set inet filter $BLOCK_SET { type ipv4_addr\; flags timeout\; } 2>/dev/null
# Clear the existing set elements
sudo nft flush set inet filter $BLOCK_SET
# Populate the set with IPs from the cleaned threat list
while IFS= read -r ip; do
sudo nft add element inet filter $BLOCK_SET { $ip }
done < $TMP_FILE.cleaned
echo "Threat list updated successfully." | tee >(logger)
EOF
# Make the script executable
chmod +x /usr/local/bin/update_nft_threatlist.sh
# Create a systemd service file for the threat list update
cat <<EOF >/etc/systemd/system/rfwb-nft-threatlist.service
[Unit]
Description=RFWB NFTables Threat List Updater
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/update_nft_threatlist.sh
[Install]
WantedBy=multi-user.target
EOF
# Create a systemd timer to run the service daily at 4 AM
cat <<EOF >/etc/systemd/system/rfwb-nft-threatlist.timer
[Unit]
Description=Run RFWB NFTables Threat List Updater Daily
[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
# Reload systemd, enable and start the timer
sudo systemctl daemon-reload
sudo systemctl enable rfwb-nft-threatlist.service
sudo systemctl start rfwb-nft-threatlist.service
sudo systemctl enable rfwb-nft-threatlist.timer
sudo systemctl start rfwb-nft-threatlist.timer
echo -e "${GREEN}Threat list update service and timer configured successfully.${RESET}" | tee >(logger)
# Validate the update
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}Threat list updated and loaded into nftables successfully.${RESET}" | tee >(logger)
echo -e "${GREEN}Threat list updates will run everyday at 4:00 (A.M.)${RESET}" | tee >(logger)
else
echo -e "${RED}Failed to update the threat list.${RESET}" | tee >(logger)
fi