Dimungkinkan untuk menutup koneksi http tanpa mengirimkan respons apa pun ke klien. Namun lebih terlibat. Seharusnya tidak sesulit ini.
Aturan Tabel IP:
iptables -t raw -I PREROUTING 1 -m recent --rsource --mask 255.255.255.0 --update --seconds 259200 --name DYN_DROP_IPv4 -j DROP
iptables -t raw -I OUTPUT 1 -m recent --rsource --mask 255.255.255.0 --update --seconds 259200 --name DYN_DROP_IPv4 -j DROP
ip6tables -t raw -I PREROUTING 1 -m recent --rsource --mask ffff:ffff:ffff:ffff:0:0:0:0 --update --seconds 259200 --name DYN_DROP_IPv6 -j DROP
ip6tables -t raw -I OUTPUT 1 -m recent --rsource --mask ffff:ffff:ffff:ffff:0:0:0:0 --update --seconds 259200 --name DYN_DROP_IPv6 -j DROP
httpd config aturan penulisan ulang untuk menjalankan skrip:
# The network mask must be the same as the iptables rule mask
Define DynDropIP_QueryString '\
?action=+\
&addr=%{REMOTE_ADDR}\
&port=%{REMOTE_PORT}\
&mask_ipv4=255.255.255.0\
&mask_ipv6=ffff:ffff:ffff:ffff:0:0:0:0\
&remote_host=%{REMOTE_HOST}\
&server_name=%{SERVER_NAME}\
&server_port=%{SERVER_PORT}\
&request_method=%{REQUEST_METHOD}\
&request_uri=%{REQUEST_URI}\
&http_user_agent=%{HTTP_USER_AGENT}\
'
Define BAD_REQUESTS_REGEX '\
^/./|\
^/\.|\
^/[0-9]+|\
^/admin|\
'
Define BAD_BOTS_REGEX '\
^.$|\
11A465|\
Ahrefs|\
ArchiveBot|\
AspiegelBot|\
Baiduspider|\
'
RewriteCond %{REQUEST_URI} ${BAD_REQUESTS_REGEX} [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ${BAD_BOTS_REGEX} [NC]
# Dynamic Drop IP Script
RewriteRule ^.* /cgi-bin/DynDropIP${DynDropIP_QueryString} [PT,E=dontlog,L,END]
UnDefine DynDropIP_QueryString
UnDefine BAD_REQUESTS_REGEX
UnDefine BAD_BOTS_REGEX
cgi-bin/DynDropIP
#!/bin/sh
main() {
# Pass query string trough to the named pipe (FIFO file) daemon; Redirect stderr to bit bucket
fifo_dir='/var/run/DynDropIP/'
fifo_file='xt_recent_fifo'
if [[ -p "${fifo_dir}${fifo_file}" ]]; then
printf "%s\n" "${QUERY_STRING}" 1>"${fifo_dir}${fifo_file}" 2>/dev/null
fi
response
}
response() {
# Allow a few seconds for the firewall to be updated before responding (desire firewall to block the response)
sleep 3
# Set the HTTP response headers (404 and content type)
# end of HTTP headers (empty line i.e. 2nd consecutive line feed)
# Send 404 error page (duplicate of Apache 2.4.6 default 404 page (en))
printf "%s\n%s\n\n%s\n" \
"Status: 404 Not Found" \
"Content-type: text/html; charset=iso-8859-1" \
"\
<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ${REQUEST_URI} was not found on this server.</p>
</body></html>\
"
}
main
/usr/local/libexec/DynDropIP/xt_recent_fifo.sh
(jalankan skrip ini untuk memulai fifo dan daemon)
#!/bin/bash
fifo_dir='/var/run/DynDropIP/'
fifo_file='xt_recent_fifo'
daemon='/usr/local/libexec/DynDropIP/xt_recent_fifo_daemon.sh'
# Prep and clean first
# If fifo dir is not a dir remove and make dir
if [[ ! -d "${fifo_dir}" ]]; then
rm -f "${fifo_dir}"
mkdir -p "${fifo_dir}"
fi
# If fifo file exists remove
[ -a "${fifo_dir}${fifo_file}" ] || \
[ -e "${fifo_dir}${fifo_file}" ] || \
[ -f "${fifo_dir}${fifo_file}" ] || \
[ -h "${fifo_dir}${fifo_file}" ] || \
[ -p "${fifo_dir}${fifo_file}" ] && \
rm -f "${fifo_dir}${fifo_file}"
mkfifo -m 666 "${fifo_dir}${fifo_file}"
# For SELinux - Allow apache user to write to the fifo
chcon -t httpd_sys_rw_content_t "${fifo_dir}${fifo_file}"
tail -f "${fifo_dir}${fifo_file}" | "${daemon}" &
/usr/local/libexec/DynDropIP/xt_recent_fifo_daemon.sh
#!/bin/bash
main() {
# Initialize IP address regex pattern vars
IP_RegEx
# Expected query string parameters: action (+/-), addr, port, mask_ipv4, mask_ipv6
while read QUERY_STRING
do
# Parse the query string into associative array
while IFS='=' read -r -d '&' key value && [[ -n "$key" ]]; do
declare $key="$value"
done <<<"${QUERY_STRING}&"
if validate; then
if process_address; then
update_iptables
logit
# response
destroy_tcp_socket
fi
fi
done < "${1:-/dev/stdin}"
}
# Validate action, address and mask parameters
validate() {
# Verify action parameter
if [[ "${action}" != "+" && "${action}" != "-" ]]; then
return 1 # failed: invalid action
fi
# Verify address and mask, set ip version if okay
if [[ "${addr}" =~ ^${IPV4ADDR}$ && "${mask_ipv4}" =~ ^${IPV4ADDR}$ ]]; then
ipv=4
elif [[ "${addr}" =~ ^${IPV6ADDR}$ && "${mask_ipv6}" =~ ^${IPV6ADDR}$ ]]; then
ipv=6
else
return 2 # failed: invalid address or network mask
fi
}
# Process IPvN address
process_address() {
if [[ $ipv -eq 4 ]]; then
ipv4_network_mask
if ! [[ "${maddr}" =~ ^${IPV4ADDR}$ ]]; then
return 4 # failed: invalid masked ipv4 address
fi
elif [[ $ipv -eq 6 ]]; then
ipv6_expand_address
ipv6_native_notation
ipv6_network_mask
if ! [[ "${maddr}" =~ ^${IPV6ADDR}$ ]]; then
return 6 # failed: invalid masked ipv6 address
fi
fi
}
# Compress IPv6 address (retain IPv4 dotted decimal or IPv6 native notation)
compress_address() {
if [[ $addr =~ ^((${IPV6SEG}:){6})((${IPV6SEG}:${IPV6SEG})|(${IPV4ADDR}))$ ]]; then
local IPv6_Segments IPv4_Segments pattern
IPv6_Segments=${BASH_REMATCH[1]}${BASH_REMATCH[4]}
IPv4_Segments=${BASH_REMATCH[5]}
# Suppress hextet leading zeros; Three passes to get each of three
IPv6_Segments=${IPv6_Segments//:0/:} && IPv6_Segments=${IPv6_Segments//:0/:} && IPv6_Segments=${IPv6_Segments//:0/:}
# Reconstitute empty hextets with single zero; Two passes to get every other one
IPv6_Segments=${IPv6_Segments//::/:0:} && IPv6_Segments=${IPv6_Segments//::/:0:}
# First hextet special cases (0:)
[[ $IPv6_Segments =~ ^0*([[:xdigit:]]+)(.*) ]] && IPv6_Segments="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
# Last hextet special cases (:0, only if not followed by IPv4 segment)
[[ $IPv6_Segments =~ [^:]:$ && -z $IPv4_Segments ]] && IPv6_Segments=$IPv6_Segments'0'
# Compress longest contiguous hextets of zero to "::" (leftmost tiebreaker).
for (( i=7; $i>=1; i-- ))
do
pattern=''
for (( j=0; $j<$i; j++ ))
do
pattern+=':0'
done
# Compress at beginning
[[ $IPv6_Segments =~ ^0$pattern ]] && IPv6_Segments=${IPv6_Segments/0$pattern/::} && break
# Compress in the middle or at end
[[ $IPv6_Segments =~ $pattern:0 ]] && IPv6_Segments=${IPv6_Segments/$pattern:0/::} && break
done
# Put address together and remove extra triple colons
addr=$IPv6_Segments$IPv4_Segments
addr=${addr/:::/::}
fi
}
# Expand IPv6 Address (retain dotted decimal or native notation)
ipv6_expand_address() {
local hextests num_colons additional_hextets
# Number of hextets in an expanded IPv6 address (native notation)
hextets=8
# How many colons in address
num_colons=${addr//[^:]/}
num_colons=${#num_colons}
# Is address IPv4 dotted decimal notation
[[ $addr =~ :${IPV4ADDR}$ ]] && hextets=$((hextets-1)) # ::ffff:0:0/96, ::ffff:0:0:0/96, 64:ff9b::/96
# Fix up beginning and end
[[ $addr =~ ^:: ]] && addr='0'$addr
[[ $addr =~ ::$ ]] && addr=$addr'0'
# Create additional hextets
additional_hextets=':'
for (( i=$num_colons; $i<$hextets; i++ ))
do
additional_hextets+='0:'
done
# Insert additional hextets (replace ::)
addr=${addr/::/$additional_hextets}
}
# Convert from IPv4 dotted decimal to IPv6 native notation (retain compressed / expanded)
ipv6_native_notation() {
local expanded_flag
# Ensure working with an expanded address
[[ $addr =~ :: ]] && ipv6_expand_address && expanded_flag=1
# Is address IPv4 dotted decimal notation
if [[ $addr =~ ^(.*:)(${IPV4ADDR})$ ]]; then
local IPv6_Segments IPv4_Segments
local s1 s2 s3 s4 s1s2 s3s4
IFS=. read -r s1 s2 s3 s4 <<< ${BASH_REMATCH[2]} # IPv4 Segments 1, 2, 3, & 4
s1s2=$(( ($s1 * 0x100) + $s2 )) # Hextet 7
s3s4=$(( ($s3 * 0x100) + $s4 )) # Hextet 8
IPv6_Segments=${BASH_REMATCH[1]} # Hextets 1, 2, 3, 4, 5, 6
IPv4_Segments=$( printf "%x:%x" "$s1s2" "$s3s4" ) # As Hextets 7 & 8
# Return converted native notation address (expanded)
if [[ -n $IPv6_Segments && -n $IPv4_Segments ]]; then
addr=$IPv6_Segments$IPv4_Segments
fi
fi
# Revert expansion
[[ $expanded_flag -eq 1 ]] && compress_address
}
# Convert from IPv6 native to IPv4 dotted decimal notation (retain compressed / expanded)
ipv6_dotted_decimal_notation() {
local expanded_flag
# Ensure working with an expanded address
[[ $addr =~ :: ]] && ipv6_expand_address && expanded_flag=1
# Is address IPv6 native notation
if [[ $addr =~ ^(.*:)(${IPV6SEG}:${IPV6SEG})$ ]]; then
local IPv6_Segments IPv4_Segments
local s1 s2 UB LB
IFS=: read -r s1 s2 <<< ${BASH_REMATCH[2]} # IPv6 Segments 7 & 8
UB=$((0xFF00)) # Upper Byte mask
LB=$((0x00FF)) # Lower Byte mask
IPv6_Segments=${BASH_REMATCH[1]} # Hextets 1, 2, 3, 4, 5, 6
IPv4_Segments=$(((16#$s1 & $UB) / $LB)).$((16#$s1 & $LB)).$(((16#$s2 & $UB) / $LB)).$((16#$s2 & $LB))
# Return converted dotted decimal notation address (expanded)
if [[ -n $IPv6_Segments && -n $IPv4_Segments ]]; then
addr=$IPv6_Segments$IPv4_Segments
fi
fi
# Revert expansion
[[ $expanded_flag -eq 1 ]] && compress_address
}
# Apply IPv4 network mask
ipv4_network_mask() {
local s1 s2 s3 s4
local m1 m2 m3 m4
mask=$mask_ipv4 # Mask is also used in logit
IFS=. read -r s1 s2 s3 s4 <<< $addr
IFS=. read -r m1 m2 m3 m4 <<< $mask
maddr="$((s1 & m1)).$((s2 & m2)).$((s3 & m3)).$((s4 & m4))"
}
# Apply IPv6 network mask
ipv6_network_mask() {
local s1 s2 s3 s4 s5 s6 s7 s8
local m1 m2 m3 m4 m5 m6 m7 m8
mask=$mask_ipv6 # Mask is also used in logit
IFS=: read -r s1 s2 s3 s4 s5 s6 s7 s8 <<< $addr
IFS=: read -r m1 m2 m3 m4 m5 m6 m7 m8 <<< $mask
maddr=$( \
printf "%x:%x:%x:%x:%x:%x:%x:%x" \
"$((0x$s1 & 0x$m1))" "$((0x$s2 & 0x$m2))" "$((0x$s3 & 0x$m3))" "$((0x$s4 & 0x$m4))" \
"$((0x$s5 & 0x$m5))" "$((0x$s6 & 0x$m6))" "$((0x$s7 & 0x$m7))" "$((0x$s8 & 0x$m8))" \
)
}
# Update table
update_iptables() {
# Add/Remove validated address to/from the xt_recent table (action parameter +/- determines add/remove)
# Redirect both stdout & stderr to null device so as not to inadvertently provide it to web user
if [[ -n $action && -n $maddr && -n $ipv ]]; then
printf "%s%s" $action $maddr 2>/dev/null \
|/usr/bin/tee /proc/net/xt_recent/DYN_DROP_IPv$ipv \
1>/dev/null 2>/dev/null
fi
}
# Log entry
logit() {
local log_dir='/var/log/iptables/DYN_DROP_IP/'
local log_file='DYN_DROP_IPv'$ipv'.log'
mkdir -p "$log_dir"
# Address field width padding (string length, field width, pad chr/str, pad chr/str width)
local field_width=0
[[ $ipv -eq 4 ]] && field_width=15
[[ $ipv -eq 6 ]] && field_width=39
local apad=$( logit_pad ${#addr} $field_width ' ' 4 )
local mpad=$( logit_pad ${#mask} $field_width ' ' 4 )
local mapad=$( logit_pad ${#maddr} $field_width ' ' 4 )
# Write log entry
printf '%s %s %s %s %s %s %s %s %s %s %s %s\n' \
"$( date +'%Y-%m-%d %H:%M:%S %a' )" \
"$ipv" \
"$action" \
"$addr$apad" \
"$maddr$mapad" \
"$mask$mpad" \
"$remote_host" \
"$server_name" \
"$server_port" \
"$request_method" \
"$request_uri" \
"$http_user_agent" \
>> "$log_dir$log_file"
# # Truncate to last 200 entries (skip header row)
#
# if [[ $ipv -eq 4 ]]; then
# local log_header='Date Time Day IPv Action IP Address Blocked Network Network Mask Client Web Site Scheme Method URI User Agent'
# elif [[ $ipv -eq 6 ]]; then
# local log_header='Date Time Day IPv Action IP Address Blocked Network Network Mask Client Web Site Scheme Method URI User Agent'
# fi
#
# printf '%s\n%s\n' \
# "$log_header" \
# "$(tail -n +2 $log_dir$log_file | tail -n -200)" \
# > "$log_dir$log_file"
}
# Field width padding
logit_pad() {
local str_length=$1
local field_width=$2
local pad_chr=$3
local pad_chr_width=$4 # e.g. tab width
local pad_length=$(( ($field_width - $str_length) / $pad_chr_width ))
local pad_string=''
for (( i=0; $i<$pad_length; i++ ))
do
pad_string+=$pad_chr
done
printf "%s" "$pad_string"
}
IP_RegEx() {
# IPv4 Regular Expressions
IPV4SEG='(25[0-5]|(2[0-4]|1[0-9]|[1-9])?[0-9])' # doted decimal notation; no leading 0 (octal) or 0x (hexadecimal)
IPV4ADDR='(('${IPV4SEG}'\.){3,3}('${IPV4SEG}'){1,1})'
IPV4CIDR='(3[0-2]|[12]?[0-9])'
# IPv6 Regular Expressions
IPV6SEG='[0-9a-fA-F]{1,4}' # colon hextet notation; leading 0 permitted
IPV6SEG8='('${IPV6SEG}':){7,7}('${IPV6SEG}'){1,1}' # 1:2:3:4:5:6:7:8
IPV6SEG7='('${IPV6SEG}':){1,7}(:''){1,1}' # 1:: 1:2:3:4:5:6:7::
IPV6SEG6='('${IPV6SEG}':){1,6}(:'${IPV6SEG}'){1,1}' # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
IPV6SEG5='('${IPV6SEG}':){1,5}(:'${IPV6SEG}'){1,2}' # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
IPV6SEG4='('${IPV6SEG}':){1,4}(:'${IPV6SEG}'){1,3}' # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
IPV6SEG3='('${IPV6SEG}':){1,3}(:'${IPV6SEG}'){1,4}' # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
IPV6SEG2='('${IPV6SEG}':){1,2}(:'${IPV6SEG}'){1,5}' # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
IPV6SEG1='('${IPV6SEG}':){1,1}(:'${IPV6SEG}'){1,6}' # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
IPV6SEG0=':((:'${IPV6SEG}'){1,7}|:)' # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
IPV6LLZI='[fF][eE]80:(:'${IPV6SEG}'){0,4}%[0-9a-zA-Z]{1,}' # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
IPV6V4MAP='(::|(0{1,4}:){5})[fF]{4}:'${IPV4ADDR} # ::ffff:d.d.d.d (::ffff:0:0/96 IPv4-mapped IPv6 addresses)
IPV6V4TRN='(::|(0{1,4}:){4})[fF]{4}:0{1,4}:'${IPV4ADDR} # ::ffff:0:d.d.d.d (::ffff:0:0:0/96 IPv4-translated addresses)
IPV6V4CMP='(::|(0:){6})'${IPV4ADDR} # ::d.d.d.d (IPv4-compatible (0::/96 deprecated by RFC4291))
# IPV6V4TRN='::([fF]{4}(:0{1,4}){0,1}:){0,1}'${IPV4ADDR} # ::d.d.d.d ::ffff:d.d.d.d ::ffff:0:d.d.d.d (IPv4-mapped IPv6 addresses and IPv4-translated addresses))
IPV6V4AMP='64:[fF]{2}9b:(:|(0{1,4}:){4})'${IPV4ADDR} # 64:ff9b::d.d.d.d (64:ff9b::/96 IPv4 translation addresses (algorithmic mapping RFC6052))
IPV6V4LUT='64:[fF]{2}9b:1:(:|(0{1,4}:){3})'${IPV4ADDR} # 64:ff9b:1::d.d.d.d (64:ff9b:1::/48 Local-Use IPv4/IPv6 Translation RFC8215)
# IPV6V4EMB='('${IPV6SEG}':){1,4}:'${IPV4ADDR} # 2001:db8:3:4::d.d.d.d 64:ff9b::d.d.d.d (IPv4-Embedded IPv6 Address)
IPV6ADDR='('\
'('${IPV6SEG8}')|('${IPV6SEG7}')|('${IPV6SEG6}')|('${IPV6SEG5}')|('${IPV6SEG4}')|('${IPV6SEG3}')|('${IPV6SEG2}')|('${IPV6SEG1}')|('${IPV6SEG0}')|'\
'('${IPV6LLZI}')|('${IPV6V4MAP}')|('${IPV6V4TRN}')|('${IPV6V4CMP}')|('${IPV6V4AMP}')|('${IPV6V4LUT}')'\
')'
IPV6CIDR='(12[0-8]|(1[01]|[1-9])?[0-9])'
PORT='([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])'
}
response() {
# Allow a few seconds for the firewall to be updated before responding (desire firewall to block the response)
sleep 3
# Set the HTTP response headers (404 and content type)
# end of HTTP headers (empty line i.e. 2nd consecutive line feed)
# Send 404 error page (duplicate of Apache 2.4.6 default 404 page (en))
printf "%s\n%s\n\n%s\n" \
"Status: 404 Not Found" \
"Content-type: text/html; charset=iso-8859-1" \
"\
<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ${REQUEST_URI} was not found on this server.</p>
</body></html>\
"
}
# On linux kernel >= 4.9 you can use the ss command from iproute2 with key -K
# ss -K dst 192.168.1.214 dport = 49029
# the kernel has to be compiled with CONFIG_INET_DIAG_DESTROY option enabled.
destroy_tcp_socket() {
# if [[ "${port}" =~ ^${PORT}$ ]]; then # Strictly Regex method
# local -i port="10#${port}" 2> /dev/null # Convert to integer method
# if [[ $port -ge 1 && $port -le 65535 ]]; then
# Is integer between 1 and 65535 (inclusive)
local int_regex='^[0-9]+$'
if [[ "$port" =~ $int_regex && $port -ge 1 && $port -le 65535 ]]; then
# ss -K dst $addr dport = $port
ss -K dst $addr:$port \
1> /dev/null 2> /dev/null
fi
}
main
person
NOYB
schedule
06.09.2020
Server:
. - person SLaks   schedule 30.12.2012nph-
CGI? Jika Anda tidak mengeluarkan apa pun dari skrip tersebut, skrip tersebut akan diterjemahkan ke klien HTTP yang tidak menerima apa pun. - person Celada   schedule 31.12.2012nph-
skrip CGI, oh, mungkin lebih dari 15 tahun. Anda mungkin lebih baik mencarinya di Google daripada mendapatkan contoh dari saya. Ini adalah cara untuk memberi tahu server web agar hanya membuang keluaran dari skrip CGI ke klien alih-alih melakukan pasca-pemrosesan dan menambahkan headernya sendiri. Lagipula itu mungkin tidak membantu Anda jika ingin menggunakan PHP, karena PHP umumnya dijalankan bukan sebagai skrip CGI tetapi langsung melalui modul Apache. - person Celada   schedule 31.12.2012ServerSignature Off
. Ini bukan yang Anda inginkan tetapi ini harusnya berhasil. edit oh Anda telah mengedit pertanyaan Anda, uhmm, Anda dapat melakukan pendekatan di mana Anda memiliki file .php umum untuk mendeteksi peretasan, dan menutup koneksi jika kondisi terpenuhi. Dan sertakan ke semua file Anda. Atau semacamnya, hanya ideku. - person madziikoy   schedule 31.12.2012