Apakah mungkin untuk menutup koneksi http tanpa respons apa pun?

Bagaimana saya bisa menutup koneksi http dengan Apache tanpa respons apa pun? Saya ingin menutup koneksi tanpa respons apa pun terhadap permintaan jika saya mendeteksi bahwa permintaan tersebut adalah serangan peretasan.

Sekarang saya punya sesuatu seperti itu:

GET / HTTP/1.0
User-Agent: Hacking-Tool

HTTP/1.1 403 Forbidden
Date: Sun, 30 Dec 2012 19:00:56 GMT
Server: Apache/2.2.0 (Linux/SUSE) mod_ssl/2.2.0 PHP/5.1.2 SVN/1.4.6
Content-Length: 13
Connection: close
Content-Type: plain/text; charset=utf-8

Stop hacking!

Bagaimana caranya saya cukup menutup koneksi agar hacker tidak dapat menebak bahwa saya menjalankan sistem linux. Saya tahu bahwa saya dapat mengurangi tanda tangan server, ini tidak masalah.


person rekire    schedule 30.12.2012    source sumber
comment
Anda cukup menutup koneksi TCP. Anda juga dapat menghapus header Server:.   -  person SLaks    schedule 30.12.2012
comment
Saya memperbarui pertanyaan saya bagaimana cara menutup koneksi. Header server tidak dapat dihapus sejauh ini saya tahu.   -  person rekire    schedule 30.12.2012
comment
Lebih disukai adalah PHP, mati atau keluar saja akan mengembalikan beberapa keluaran yang ingin saya hindari.   -  person rekire    schedule 30.12.2012
comment
Sudahkah Anda mencoba skrip nph- 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.2012
comment
@Celada bisakah Anda memberi saya contoh?   -  person rekire    schedule 31.12.2012
comment
@rekire Sejujurnya, saya belum pernah menggunakan nph- 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.2012
comment
Saya kira Anda dapat mencoba menyembunyikan detail server melalui file konfigurasi. coba ServerSignature 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


Jawaban (2)


Anda telah mengajukan dua pertanyaan, cobalah untuk menghindarinya :).

Pertama adalah Anda ingin mencegah sidik jari OS/aplikasi. Anda dapat melakukan ini dengan menghapus header server, dan mengubah halaman kesalahan Apache... dan masih ada kemungkinan penyerang dapat menebak os dan server http Anda. Anda dapat menggunakan Apache Mod Security untuk membantu Anda.

Kedua adalah menutup koneksi tanpa header respons http yang tepat setelah level aplikasi, eksekusi logika (aplikasi Anda menentukan apakah permintaan merupakan upaya peretasan). Di php saya pikir Anda tidak bisa melakukan ini. Ketika parser dijalankan, saya pikir respons sudah disiapkan oleh Apache, dan jika parser tidak mengembalikan apa pun, respons kosong atau respons kesalahan akan dikirim oleh Apache sendiri. Dan saya pikir jika Anda menggunakan beberapa penyaringan header, dan hanya mengembalikan string biasa "Upaya peretasan terdeteksi. Administrator telah diberitahu. Dampak hukum mungkin terjadi." Anda akan menakuti beberapa skrip kiddie dengan cukup baik.

P.S. Saya ingin tahu upaya peretasan apa yang dapat dideteksi oleh aplikasi Anda? Apakah ini validasi token CSRF? Apakah ini upaya akses sederhana yang tidak diautentikasi, atau bentuk pemeriksaan Otorisasi lainnya? Atau mekanisme keamanan yang Anda kembangkan?

person damiankolasa    schedule 02.01.2013
comment
Bagian tentang menyembunyikan header Server hanya untuk menjelaskan apa yang ingin saya sembunyikan, tapi ini bukan bagian dari pertanyaan saya (hanya di komentar). Sejauh ini saya membaca sesuatu tentang mod secutiry. Saya rasa ini semacam proxy bukan? Tentang cara saya mendeteksinya, pada dasarnya saya menggunakan mod rewrite untuk itu. Jadi jika seseorang mencoba mengakses phpmyadmin yang tidak ada, saya tahu ini adalah serangan. Jadi saya ingin menutup koneksi dan memasukkan ip tersebut ke daftar hitam firewall saya. - person rekire; 02.01.2013
comment
keamanan mod hanyalah modul apache yang memfilter data masuk dan keluar. Dan dapat membantu Anda mengamankan, atau menganonimkan aplikasi dalam kasus Anda. Dan saya tidak akan repot-repot menutup koneksi tanpa header apa pun. Saya hanya akan membalas pesan sederhana itu saja, ini bukan beban pemrosesan yang besar untuk Apache, jadi Anda tidak benar-benar membuka vektor serangan DoS baru di aplikasi Anda. - person damiankolasa; 02.01.2013
comment
Yah IMHO itu tidak membuka vektor serangan apa pun jika saya menutup koneksi dan memblokir semua koneksi di masa depan dari host itu. Itu tidak akan melindungi saya terhadap DDOS tetapi untuk DOS. Saya akan memeriksa mod itu di rumah. - person rekire; 02.01.2013
comment
Untuk lebih jelasnya, menutup koneksi alih-alih respons palsu, tidak melakukan apa pun untuk perlindungan, pemblokiran firewall tidak. Jadi jika Anda menambahkan entri pemblokiran di FW Anda, maka itu tidak mengubah apa pun, jika koneksi awal ditutup tanpa respons apa pun atau jika resp, cepat dan sederhana. - person damiankolasa; 02.01.2013
comment
Ide saya adalah penyerang tidak dapat mengetahui apa yang ada di balik port ini. Mungkin saja di balik port ini ada mis. skype atau messenger lain. Saya hanya tidak ingin memberikan petunjuk. Namun secara umum Anda benar. +1 untuk saat ini, jika ini berfungsi dengan baik, Anda mendapatkan jawaban yang diterima ;-) - person rekire; 02.01.2013

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
comment
Solusi luar biasa, ketika saya punya waktu luang saya akan memeriksanya. - person rekire; 06.09.2020