mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 20:14:56 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5104269605 | ||
![]() |
4ee209416f | ||
![]() |
43df040e05 | ||
![]() |
f59a4eb9d9 | ||
![]() |
a238253509 | ||
![]() |
4547e4c5cc | ||
![]() |
5d94a36d22 | ||
![]() |
9d5b2e2e0e | ||
![]() |
f973577ec0 | ||
![]() |
a35feefa0f | ||
![]() |
a1b3d81ccb | ||
![]() |
6504f251c6 | ||
![]() |
1c67775d10 | ||
![]() |
7327cd725b | ||
![]() |
5c8aecdd56 | ||
![]() |
5ad9de75d4 |
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT([xtables-addons], [3.12])
|
AC_INIT([xtables-addons], [3.15])
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
@@ -57,7 +57,7 @@ if test -n "$kbuilddir"; then
|
|||||||
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
echo "WARNING: Version detection did not succeed. Continue at own luck.";
|
||||||
else
|
else
|
||||||
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
echo "$kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||||
if test "$kmajor" -gt 5 -o "$kmajor" -eq 5 -a "$kminor" -gt 10; then
|
if test "$kmajor" -gt 5 -o "$kmajor" -eq 5 -a "$kminor" -gt 11; then
|
||||||
echo "WARNING: That kernel version is not officially supported yet. Continue at own luck.";
|
echo "WARNING: That kernel version is not officially supported yet. Continue at own luck.";
|
||||||
elif test "$kmajor" -eq 5 -a "$kminor" -ge 0; then
|
elif test "$kmajor" -eq 5 -a "$kminor" -ge 0; then
|
||||||
:
|
:
|
||||||
|
@@ -1,3 +1,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
v3.15 (2021-02-05)
|
||||||
|
==================
|
||||||
|
- xt_ECHO: support new function signature of security_skb_classify_flow
|
||||||
|
- xt_lscan: add --mirai option
|
||||||
|
- Support for Linux 5.11
|
||||||
|
|
||||||
|
|
||||||
|
v3.14 (2020-11-24)
|
||||||
|
==================
|
||||||
|
- DELUDE, ECHO, TARPIT: use actual tunnel socket (ip_route_me_harder).
|
||||||
|
- geoip: scripts for use with MaxMind DB have been brought back,
|
||||||
|
partly under new names.
|
||||||
|
- Gave xt_geoip_fetch a more fitting name, xt_geoip_query.
|
||||||
|
|
||||||
|
|
||||||
|
v3.13 (2020-11-20)
|
||||||
|
==================
|
||||||
|
- Support for Linux 4.19.158 and 5.4.78 (ip_route_me_harder)
|
||||||
|
|
||||||
|
|
||||||
v3.12 (2020-11-19)
|
v3.12 (2020-11-19)
|
||||||
==================
|
==================
|
||||||
- Support for Linux 5.10 and 5.9.9 API
|
- Support for Linux 5.10 and 5.9.9 API
|
||||||
|
@@ -22,7 +22,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) || \
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) || \
|
||||||
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 9) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
|
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 9) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) || \
|
||||||
|
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 78) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0) || \
|
||||||
|
LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 158) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
|
||||||
#else
|
#else
|
||||||
# define ip_route_me_harder(xnet, xsk, xskb, xaddrtype) ip_route_me_harder((xnet), (xskb), (xaddrtype))
|
# define ip_route_me_harder(xnet, xsk, xskb, xaddrtype) ip_route_me_harder((xnet), (xskb), (xaddrtype))
|
||||||
# define ip6_route_me_harder(xnet, xsk, xskb) ip6_route_me_harder((xnet), (xskb))
|
# define ip6_route_me_harder(xnet, xsk, xskb) ip6_route_me_harder((xnet), (xskb))
|
||||||
|
@@ -24,6 +24,7 @@ static const struct option lscan_mt_opts[] = {
|
|||||||
{.name = "synscan", .has_arg = false, .val = 's'},
|
{.name = "synscan", .has_arg = false, .val = 's'},
|
||||||
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
{.name = "cnscan", .has_arg = false, .val = 'c'},
|
||||||
{.name = "grscan", .has_arg = false, .val = 'g'},
|
{.name = "grscan", .has_arg = false, .val = 'g'},
|
||||||
|
{.name = "mirai", .has_arg = false, .val = 'm'},
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +36,8 @@ static void lscan_mt_help(void)
|
|||||||
" --stealth Match TCP Stealth packets\n"
|
" --stealth Match TCP Stealth packets\n"
|
||||||
" --synscan Match TCP SYN scans\n"
|
" --synscan Match TCP SYN scans\n"
|
||||||
" --cnscan Match TCP Connect scans\n"
|
" --cnscan Match TCP Connect scans\n"
|
||||||
" --grscan Match Banner Grabbing scans\n");
|
" --grscan Match Banner Grabbing scans\n"
|
||||||
|
" --mirai Match TCP scan with ISN = dest. IP\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lscan_mt_parse(int c, char **argv, int invert,
|
static int lscan_mt_parse(int c, char **argv, int invert,
|
||||||
@@ -45,16 +47,19 @@ static int lscan_mt_parse(int c, char **argv, int invert,
|
|||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
info->match_cn = true;
|
info->match_fl3 |= LSCAN_FL3_CN;
|
||||||
return true;
|
return true;
|
||||||
case 'g':
|
case 'g':
|
||||||
info->match_gr = true;
|
info->match_fl4 |= LSCAN_FL4_GR;
|
||||||
|
return true;
|
||||||
|
case 'm':
|
||||||
|
info->match_fl1 |= LSCAN_FL1_MIRAI;
|
||||||
return true;
|
return true;
|
||||||
case 's':
|
case 's':
|
||||||
info->match_syn = true;
|
info->match_fl2 |= LSCAN_FL2_SYN;
|
||||||
return true;
|
return true;
|
||||||
case 'x':
|
case 'x':
|
||||||
info->match_stealth = true;
|
info->match_fl1 |= LSCAN_FL1_STEALTH;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -68,14 +73,16 @@ static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
|
|||||||
{
|
{
|
||||||
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
const struct xt_lscan_mtinfo *info = (const void *)(match->data);
|
||||||
|
|
||||||
if (info->match_stealth)
|
if (info->match_fl1 & LSCAN_FL1_STEALTH)
|
||||||
printf(" --stealth ");
|
printf(" --stealth ");
|
||||||
if (info->match_syn)
|
if (info->match_fl2 & LSCAN_FL2_SYN)
|
||||||
printf(" --synscan ");
|
printf(" --synscan ");
|
||||||
if (info->match_cn)
|
if (info->match_fl3 & LSCAN_FL3_CN)
|
||||||
printf(" --cnscan ");
|
printf(" --cnscan ");
|
||||||
if (info->match_gr)
|
if (info->match_fl4 & LSCAN_FL4_GR)
|
||||||
printf(" --grscan ");
|
printf(" --grscan ");
|
||||||
|
if (info->match_fl1 & LSCAN_FL1_MIRAI)
|
||||||
|
printf(" --mirai ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lscan_mt_print(const void *ip,
|
static void lscan_mt_print(const void *ip,
|
||||||
|
@@ -27,6 +27,11 @@ warranted single-direction data flows, usually bulk data transfers such as
|
|||||||
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
|
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
|
||||||
ports where a protocol runs that is guaranteed to do a bidirectional exchange
|
ports where a protocol runs that is guaranteed to do a bidirectional exchange
|
||||||
of bytes.
|
of bytes.
|
||||||
|
.TP
|
||||||
|
\fB\-\-mirai\fP
|
||||||
|
Match if the TCP ISN is equal to the IPv4 destination address; this is used
|
||||||
|
by the devices in the Mirai botnet as a form of TCP SYN scan, so you will
|
||||||
|
have to explicitly specify --syn for the rule.
|
||||||
.PP
|
.PP
|
||||||
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
|
||||||
so be advised to carefully use xt_lscan in conjunction with blocking rules,
|
so be advised to carefully use xt_lscan in conjunction with blocking rules,
|
||||||
|
@@ -247,12 +247,11 @@ pknock_seq_show(struct seq_file *s, void *v)
|
|||||||
seq_printf(s, "expir_time=%lu [secs] ", time);
|
seq_printf(s, "expir_time=%lu [secs] ", time);
|
||||||
}
|
}
|
||||||
if (peer->status == ST_ALLOWED && rule->autoclose_time != 0) {
|
if (peer->status == ST_ALLOWED && rule->autoclose_time != 0) {
|
||||||
|
unsigned long x = ktime_get_seconds();
|
||||||
|
unsigned long y = peer->login_sec + rule->autoclose_time * 60;
|
||||||
time = 0;
|
time = 0;
|
||||||
if (time_before(get_seconds(), peer->login_sec +
|
if (time_before(x, y))
|
||||||
rule->autoclose_time * 60))
|
time = y - x;
|
||||||
time = peer->login_sec +
|
|
||||||
rule->autoclose_time * 60 -
|
|
||||||
get_seconds();
|
|
||||||
seq_printf(s, "autoclose_time=%lu [secs] ", time);
|
seq_printf(s, "autoclose_time=%lu [secs] ", time);
|
||||||
}
|
}
|
||||||
seq_printf(s, "\n");
|
seq_printf(s, "\n");
|
||||||
@@ -312,8 +311,9 @@ static void update_rule_gc_timer(struct xt_pknock_rule *rule)
|
|||||||
static inline bool
|
static inline bool
|
||||||
autoclose_time_passed(const struct peer *peer, unsigned int autoclose_time)
|
autoclose_time_passed(const struct peer *peer, unsigned int autoclose_time)
|
||||||
{
|
{
|
||||||
return peer != NULL && autoclose_time != 0 && time_after(get_seconds(),
|
unsigned long x = ktime_get_seconds();
|
||||||
peer->login_sec + autoclose_time * 60);
|
unsigned long y = peer->login_sec + autoclose_time * 60;
|
||||||
|
return peer != NULL && autoclose_time != 0 && time_after(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -335,7 +335,7 @@ is_interknock_time_exceeded(const struct peer *peer, unsigned int max_time)
|
|||||||
static inline bool
|
static inline bool
|
||||||
has_logged_during_this_minute(const struct peer *peer)
|
has_logged_during_this_minute(const struct peer *peer)
|
||||||
{
|
{
|
||||||
return peer != NULL && peer->login_sec / 60 == get_seconds() / 60;
|
return peer != NULL && peer->login_sec / 60 == ktime_get_seconds() / 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -727,7 +727,7 @@ has_secret(const unsigned char *secret, unsigned int secret_len, uint32_t ipsrc,
|
|||||||
hexresult = kzalloc(hexa_size, GFP_ATOMIC);
|
hexresult = kzalloc(hexa_size, GFP_ATOMIC);
|
||||||
if (hexresult == NULL)
|
if (hexresult == NULL)
|
||||||
return false;
|
return false;
|
||||||
epoch_min = get_seconds() / 60;
|
epoch_min = ktime_get_seconds() / 60;
|
||||||
|
|
||||||
ret = crypto_shash_setkey(crypto.tfm, secret, secret_len);
|
ret = crypto_shash_setkey(crypto.tfm, secret, secret_len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -826,7 +826,7 @@ update_peer(struct peer *peer, const struct xt_pknock_mtinfo *info,
|
|||||||
if (is_last_knock(peer, info)) {
|
if (is_last_knock(peer, info)) {
|
||||||
peer->status = ST_ALLOWED;
|
peer->status = ST_ALLOWED;
|
||||||
pk_debug("ALLOWED", peer);
|
pk_debug("ALLOWED", peer);
|
||||||
peer->login_sec = get_seconds();
|
peer->login_sec = ktime_get_seconds();
|
||||||
if (nl_multicast_group > 0)
|
if (nl_multicast_group > 0)
|
||||||
msg_to_userspace_nl(info, peer, nl_multicast_group);
|
msg_to_userspace_nl(info, peer, nl_multicast_group);
|
||||||
return true;
|
return true;
|
||||||
|
@@ -25,8 +25,8 @@
|
|||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
#define PFX KBUILD_MODNAME ": "
|
#define PFX KBUILD_MODNAME ": "
|
||||||
|
|
||||||
static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
|
static void delude_send_reset(struct sk_buff *oldskb,
|
||||||
unsigned int hook)
|
const struct xt_action_param *par)
|
||||||
{
|
{
|
||||||
struct tcphdr _otcph, *tcph;
|
struct tcphdr _otcph, *tcph;
|
||||||
const struct tcphdr *oth;
|
const struct tcphdr *oth;
|
||||||
@@ -51,7 +51,8 @@ static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check checksum */
|
/* Check checksum */
|
||||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
if (nf_ip_checksum(oldskb, par->state->hook, ip_hdrlen(oldskb),
|
||||||
|
IPPROTO_TCP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
|
||||||
@@ -108,20 +109,21 @@ static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
|
|||||||
addr_type = RTN_UNSPEC;
|
addr_type = RTN_UNSPEC;
|
||||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
if (hook != NF_INET_FORWARD || ((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
|
if (par->state->hook != NF_INET_FORWARD ||
|
||||||
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
|
||||||
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
|
||||||
#else
|
#else
|
||||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
if (par->state->hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||||
nskb->nf_bridge->physoutdev))
|
nskb->nf_bridge->physoutdev))
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
if (hook != NF_INET_FORWARD)
|
if (par->state->hook != NF_INET_FORWARD)
|
||||||
#endif
|
#endif
|
||||||
addr_type = RTN_LOCAL;
|
addr_type = RTN_LOCAL;
|
||||||
|
|
||||||
/* ip_route_me_harder expects skb->dst to be set */
|
/* ip_route_me_harder expects skb->dst to be set */
|
||||||
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
||||||
if (ip_route_me_harder(net, nskb->sk, nskb, addr_type))
|
if (ip_route_me_harder(par_net(par), par->state->sk, nskb, addr_type))
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
else
|
else
|
||||||
niph = ip_hdr(nskb);
|
niph = ip_hdr(nskb);
|
||||||
@@ -134,8 +136,7 @@ static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
|
|||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
|
ip_local_out(par_net(par), nskb->sk, nskb);
|
||||||
ip_local_out(net, nskb->sk, nskb);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -150,7 +151,7 @@ delude_tg(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
* a problem, as that is supported since Linux 2.6.35. But since we do not
|
* a problem, as that is supported since Linux 2.6.35. But since we do not
|
||||||
* actually want to have a connection open, we are still going to drop it.
|
* actually want to have a connection open, we are still going to drop it.
|
||||||
*/
|
*/
|
||||||
delude_send_reset(par_net(par), skb, par->state->hook);
|
delude_send_reset(skb, par);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,9 +19,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
#include <linux/module.h>
|
||||||
|
#ifdef CONFIG_NF_NAT
|
||||||
#include <linux/inet.h>
|
#include <linux/inet.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
#include <linux/netfilter_ipv4.h>
|
#include <linux/netfilter_ipv4.h>
|
||||||
@@ -36,12 +37,6 @@
|
|||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
#include "xt_DNETMAP.h"
|
#include "xt_DNETMAP.h"
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_AUTHOR("Marek Kierdelewicz <marek@piasta.pl>");
|
|
||||||
MODULE_DESCRIPTION(
|
|
||||||
"Xtables: dynamic two-way 1:1 NAT mapping of IPv4 addresses");
|
|
||||||
MODULE_ALIAS("ipt_DNETMAP");
|
|
||||||
|
|
||||||
static unsigned int default_ttl = 600;
|
static unsigned int default_ttl = 600;
|
||||||
static unsigned int proc_perms = S_IRUGO | S_IWUSR;
|
static unsigned int proc_perms = S_IRUGO | S_IWUSR;
|
||||||
static unsigned int proc_uid;
|
static unsigned int proc_uid;
|
||||||
@@ -921,6 +916,18 @@ static void __exit dnetmap_tg_exit(void)
|
|||||||
xt_unregister_target(&dnetmap_tg_reg);
|
xt_unregister_target(&dnetmap_tg_reg);
|
||||||
unregister_pernet_subsys(&dnetmap_net_ops);
|
unregister_pernet_subsys(&dnetmap_net_ops);
|
||||||
}
|
}
|
||||||
|
#else /* CONFIG_NF_NAT */
|
||||||
|
static int __init dnetmap_tg_init(void)
|
||||||
|
{
|
||||||
|
pr_err("CONFIG_NF_NAT is not available in your kernel, hence this module cannot function.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
static void __exit dnetmap_tg_exit(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
module_init(dnetmap_tg_init);
|
module_init(dnetmap_tg_init);
|
||||||
module_exit(dnetmap_tg_exit);
|
module_exit(dnetmap_tg_exit);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Marek Kierdelewicz <marek@piasta.pl>");
|
||||||
|
MODULE_DESCRIPTION("Xtables: dynamic two-way 1:1 NAT mapping of IPv4 addresses");
|
||||||
|
MODULE_ALIAS("ipt_DNETMAP");
|
||||||
|
@@ -97,7 +97,11 @@ echo_tg6(struct sk_buff *oldskb, const struct xt_action_param *par)
|
|||||||
memcpy(&fl.daddr, &newip->daddr, sizeof(fl.daddr));
|
memcpy(&fl.daddr, &newip->daddr, sizeof(fl.daddr));
|
||||||
fl.fl6_sport = newudp->source;
|
fl.fl6_sport = newudp->source;
|
||||||
fl.fl6_dport = newudp->dest;
|
fl.fl6_dport = newudp->dest;
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
|
||||||
|
security_skb_classify_flow((struct sk_buff *)oldskb, flowi6_to_flowi_common(&fl));
|
||||||
|
#else
|
||||||
security_skb_classify_flow((struct sk_buff *)oldskb, flowi6_to_flowi(&fl));
|
security_skb_classify_flow((struct sk_buff *)oldskb, flowi6_to_flowi(&fl));
|
||||||
|
#endif
|
||||||
dst = ip6_route_output(net, NULL, &fl);
|
dst = ip6_route_output(net, NULL, &fl);
|
||||||
if (dst == NULL || dst->error != 0) {
|
if (dst == NULL || dst->error != 0) {
|
||||||
dst_release(dst);
|
dst_release(dst);
|
||||||
@@ -113,7 +117,7 @@ echo_tg6(struct sk_buff *oldskb, const struct xt_action_param *par)
|
|||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(newskb, oldskb);
|
nf_ct_attach(newskb, oldskb);
|
||||||
ip6_local_out(par_net(par), newskb->sk, newskb);
|
ip6_local_out(par_net(par), par->state->sk, newskb);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -191,7 +195,8 @@ echo_tg4(struct sk_buff *oldskb, const struct xt_action_param *par)
|
|||||||
|
|
||||||
/* ip_route_me_harder expects the skb's dst to be set */
|
/* ip_route_me_harder expects the skb's dst to be set */
|
||||||
skb_dst_set(newskb, dst_clone(skb_dst(oldskb)));
|
skb_dst_set(newskb, dst_clone(skb_dst(oldskb)));
|
||||||
if (ip_route_me_harder(par_net(par), newskb->sk, newskb, RTN_UNSPEC) != 0)
|
if (ip_route_me_harder(par_net(par), par->state->sk, newskb,
|
||||||
|
RTN_UNSPEC) != 0)
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
newip->ttl = ip4_dst_hoplimit(skb_dst(newskb));
|
newip->ttl = ip4_dst_hoplimit(skb_dst(newskb));
|
||||||
|
@@ -170,8 +170,8 @@ static bool tarpit_generic(struct tcphdr *tcph, const struct tcphdr *oth,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
|
static void tarpit_tcp4(const struct xt_action_param *par,
|
||||||
unsigned int hook, unsigned int mode)
|
struct sk_buff *oldskb, unsigned int mode)
|
||||||
{
|
{
|
||||||
struct tcphdr _otcph, *tcph;
|
struct tcphdr _otcph, *tcph;
|
||||||
const struct tcphdr *oth;
|
const struct tcphdr *oth;
|
||||||
@@ -191,7 +191,8 @@ static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check checksum. */
|
/* Check checksum. */
|
||||||
if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
|
if (nf_ip_checksum(oldskb, par->state->hook, ip_hdrlen(oldskb),
|
||||||
|
IPPROTO_TCP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -254,18 +255,19 @@ static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
|
|||||||
|
|
||||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||||
if (hook != NF_INET_FORWARD || ((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
|
if (par->state->hook != NF_INET_FORWARD ||
|
||||||
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF) != NULL &&
|
||||||
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
|
((struct nf_bridge_info *)skb_ext_find(nskb, SKB_EXT_BRIDGE_NF))->physoutdev))
|
||||||
#else
|
#else
|
||||||
if (hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
if (par->state->hook != NF_INET_FORWARD || (nskb->nf_bridge != NULL &&
|
||||||
nskb->nf_bridge->physoutdev != NULL))
|
nskb->nf_bridge->physoutdev != NULL))
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
if (hook != NF_INET_FORWARD)
|
if (par->state->hook != NF_INET_FORWARD)
|
||||||
#endif
|
#endif
|
||||||
addr_type = RTN_LOCAL;
|
addr_type = RTN_LOCAL;
|
||||||
|
|
||||||
if (ip_route_me_harder(net, nskb->sk, nskb, addr_type))
|
if (ip_route_me_harder(par_net(par), par->state->sk, nskb, addr_type) != 0)
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
else
|
else
|
||||||
niph = ip_hdr(nskb);
|
niph = ip_hdr(nskb);
|
||||||
@@ -287,8 +289,8 @@ static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
|
|||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, nskb->sk, nskb, NULL,
|
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, par_net(par), nskb->sk, nskb,
|
||||||
skb_dst(nskb)->dev, dst_output);
|
NULL, skb_dst(nskb)->dev, dst_output);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -296,8 +298,8 @@ static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
static void tarpit_tcp6(struct net *net, struct sk_buff *oldskb,
|
static void tarpit_tcp6(const struct xt_action_param *par,
|
||||||
unsigned int hook, unsigned int mode)
|
struct sk_buff *oldskb, unsigned int mode)
|
||||||
{
|
{
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
struct tcphdr *tcph, oth;
|
struct tcphdr *tcph, oth;
|
||||||
@@ -398,14 +400,14 @@ static void tarpit_tcp6(struct net *net, struct sk_buff *oldskb,
|
|||||||
&ipv6_hdr(nskb)->daddr, sizeof(struct tcphdr),
|
&ipv6_hdr(nskb)->daddr, sizeof(struct tcphdr),
|
||||||
IPPROTO_TCP,
|
IPPROTO_TCP,
|
||||||
csum_partial(tcph, sizeof(struct tcphdr), 0));
|
csum_partial(tcph, sizeof(struct tcphdr), 0));
|
||||||
if (ip6_route_me_harder(net, nskb->sk, nskb))
|
if (ip6_route_me_harder(par_net(par), nskb->sk, nskb))
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nskb->ip_summed = CHECKSUM_NONE;
|
nskb->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, nskb->sk, nskb, NULL,
|
NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, par_net(par), nskb->sk, nskb,
|
||||||
skb_dst(nskb)->dev, dst_output);
|
NULL, skb_dst(nskb)->dev, dst_output);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -443,7 +445,7 @@ tarpit_tg4(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
/* We are not interested in fragments */
|
/* We are not interested in fragments */
|
||||||
if (iph->frag_off & htons(IP_OFFSET))
|
if (iph->frag_off & htons(IP_OFFSET))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
tarpit_tcp4(par_net(par), skb, par->state->hook, info->variant);
|
tarpit_tcp4(par, skb, info->variant);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +486,7 @@ tarpit_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
|||||||
pr_debug("addr is not unicast.\n");
|
pr_debug("addr is not unicast.\n");
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
tarpit_tcp6(par_net(par), skb, par->state->hook, info->variant);
|
tarpit_tcp6(par, skb, info->variant);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -175,6 +175,7 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||||||
{
|
{
|
||||||
const struct xt_lscan_mtinfo *info = par->matchinfo;
|
const struct xt_lscan_mtinfo *info = par->matchinfo;
|
||||||
enum ip_conntrack_info ctstate;
|
enum ip_conntrack_info ctstate;
|
||||||
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
const struct tcphdr *tcph;
|
const struct tcphdr *tcph;
|
||||||
struct nf_conn *ctdata;
|
struct nf_conn *ctdata;
|
||||||
struct tcphdr tcph_buf;
|
struct tcphdr tcph_buf;
|
||||||
@@ -182,11 +183,14 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||||||
tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf);
|
tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf);
|
||||||
if (tcph == NULL)
|
if (tcph == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
if (info->match_fl1 & LSCAN_FL1_MIRAI && iph != NULL &&
|
||||||
|
iph->version == 4 && iph->daddr == tcph->seq)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* Check for invalid packets: -m conntrack --ctstate INVALID */
|
/* Check for invalid packets: -m conntrack --ctstate INVALID */
|
||||||
ctdata = nf_ct_get(skb, &ctstate);
|
ctdata = nf_ct_get(skb, &ctstate);
|
||||||
if (ctdata == NULL) {
|
if (ctdata == NULL) {
|
||||||
if (info->match_stealth)
|
if (info->match_fl1 & LSCAN_FL1_STEALTH)
|
||||||
return lscan_mt_stealth(tcph);
|
return lscan_mt_stealth(tcph);
|
||||||
/*
|
/*
|
||||||
* If @ctdata is NULL, we cannot match the other scan
|
* If @ctdata is NULL, we cannot match the other scan
|
||||||
@@ -212,17 +216,19 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||||||
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
|
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (info->match_syn && ctdata->mark == mark_synscan) ||
|
return (info->match_fl1 & LSCAN_FL1_STEALTH && ctdata->mark == mark_synscan) ||
|
||||||
(info->match_cn && ctdata->mark == mark_cnscan) ||
|
(info->match_fl3 & LSCAN_FL3_CN && ctdata->mark == mark_cnscan) ||
|
||||||
(info->match_gr && ctdata->mark == mark_grscan);
|
(info->match_fl4 & LSCAN_FL4_GR && ctdata->mark == mark_grscan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lscan_mt_check(const struct xt_mtchk_param *par)
|
static int lscan_mt_check(const struct xt_mtchk_param *par)
|
||||||
{
|
{
|
||||||
const struct xt_lscan_mtinfo *info = par->matchinfo;
|
const struct xt_lscan_mtinfo *info = par->matchinfo;
|
||||||
|
|
||||||
if ((info->match_stealth & ~1) || (info->match_syn & ~1) ||
|
if ((info->match_fl1 & ~(LSCAN_FL1_STEALTH | LSCAN_FL1_MIRAI)) ||
|
||||||
(info->match_cn & ~1) || (info->match_gr & ~1)) {
|
(info->match_fl2 & ~LSCAN_FL2_SYN) ||
|
||||||
|
(info->match_fl3 & ~LSCAN_FL3_CN) ||
|
||||||
|
(info->match_fl4 & ~LSCAN_FL4_GR)) {
|
||||||
printk(KERN_WARNING PFX "Invalid flags\n");
|
printk(KERN_WARNING PFX "Invalid flags\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,16 @@
|
|||||||
#ifndef _LINUX_NETFILTER_XT_LSCAN_H
|
#ifndef _LINUX_NETFILTER_XT_LSCAN_H
|
||||||
#define _LINUX_NETFILTER_XT_LSCAN_H 1
|
#define _LINUX_NETFILTER_XT_LSCAN_H 1
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LSCAN_FL1_STEALTH = 1 << 0,
|
||||||
|
LSCAN_FL1_MIRAI = 1 << 1,
|
||||||
|
LSCAN_FL2_SYN = 1 << 0,
|
||||||
|
LSCAN_FL3_CN = 1 << 0,
|
||||||
|
LSCAN_FL4_GR = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
struct xt_lscan_mtinfo {
|
struct xt_lscan_mtinfo {
|
||||||
uint8_t match_stealth, match_syn, match_cn, match_gr;
|
uint8_t match_fl1, match_fl2, match_fl3, match_fl4;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LINUX_NETFILTER_XT_LSCAN_H */
|
#endif /* _LINUX_NETFILTER_XT_LSCAN_H */
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
|
|
||||||
bin_SCRIPTS = xt_geoip_fetch xt_geoip_fetch_maxmind
|
bin_SCRIPTS = xt_geoip_query
|
||||||
|
|
||||||
pkglibexec_SCRIPTS = xt_geoip_build xt_geoip_build_maxmind xt_geoip_dl xt_geoip_dl_maxmind
|
pkglibexec_SCRIPTS = xt_geoip_build xt_geoip_build_maxmind xt_geoip_dl xt_geoip_dl_maxmind
|
||||||
|
|
||||||
man1_MANS = xt_geoip_build.1 xt_geoip_dl.1 xt_geoip_fetch.1
|
man1_MANS = xt_geoip_build.1 xt_geoip_dl.1 \
|
||||||
|
xt_geoip_build_maxmind.1 xt_geoip_dl_maxmind.1 \
|
||||||
|
xt_geoip_query.1
|
||||||
|
40
geoip/xt_geoip_build_maxmind.1
Normal file
40
geoip/xt_geoip_build_maxmind.1
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
.TH xt_geoip_build_maxmind 1 "2010-12-17" "xtables-addons" "xtables-addons"
|
||||||
|
.SH Name
|
||||||
|
.PP
|
||||||
|
xt_geoip_build_maxmind \(em convert GeoIP.csv to packed format for xt_geoip
|
||||||
|
.SH Syntax
|
||||||
|
.PP
|
||||||
|
\fI/usr/libexec/xt_geoip/\fP\fBxt_geoip_build_maxmind\fP [\fB\-D\fP
|
||||||
|
\fItarget_dir\fP] [\fB\-S\fP \fIsource_dir\fP]
|
||||||
|
.SH Description
|
||||||
|
.PP
|
||||||
|
xt_geoip_build_maxmind is used to build packed raw representations of the range
|
||||||
|
database that the xt_geoip module relies on. Since kernel memory is precious,
|
||||||
|
much of the preprocessing is done in userspace by this very building tool. One
|
||||||
|
file is produced for each country, so that no more addresses than needed are
|
||||||
|
required to be loaded into memory. The ranges in the packed database files are
|
||||||
|
also ordered, as xt_geoip relies on this property for its bisection approach to
|
||||||
|
work.
|
||||||
|
.PP
|
||||||
|
Since the script is usually installed to the libexec directory of the
|
||||||
|
xtables-addons package and this is outside $PATH (on purpose), invoking the
|
||||||
|
script requires it to be called with a path.
|
||||||
|
.PP Options
|
||||||
|
.TP
|
||||||
|
\fB\-D\fP \fItarget_dir\fP
|
||||||
|
Specifies the target directory into which the files are to be put. Defaults to ".".
|
||||||
|
.TP
|
||||||
|
\fB\-S\fP \fIsource_dir\fP
|
||||||
|
Specifies the source directory of the MaxMind CSV files. Defaults to ".".
|
||||||
|
.TP
|
||||||
|
\fB\-s\fP
|
||||||
|
"System mode". Equivalent to \fB\-D /usr/share/xt_geoip\fP.
|
||||||
|
.SH Application
|
||||||
|
.PP
|
||||||
|
Shell commands to build the databases and put them to where they are expected
|
||||||
|
(usually run as root):
|
||||||
|
.PP
|
||||||
|
xt_geoip_build_maxmind \-s
|
||||||
|
.SH See also
|
||||||
|
.PP
|
||||||
|
xt_geoip_dl_maxmind(1)
|
@@ -1,7 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ $# -eq 1 ]; then
|
||||||
|
exec <$1
|
||||||
|
elif [ $# -ne 0 ]; then
|
||||||
|
echo $(basename $0) [ licence_key_file ] 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read licence_key
|
||||||
|
|
||||||
rm -rf GeoLite2-Country-CSV_*
|
rm -rf GeoLite2-Country-CSV_*
|
||||||
|
|
||||||
wget -q http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
|
wget -q -OGeoLite2-Country-CSV.zip "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=${licence_key}&suffix=zip"
|
||||||
unzip -q GeoLite2-Country-CSV.zip
|
unzip -q GeoLite2-Country-CSV.zip
|
||||||
rm -f GeoLite2-Country-CSV.zip
|
rm -f GeoLite2-Country-CSV.zip
|
||||||
|
22
geoip/xt_geoip_dl_maxmind.1
Normal file
22
geoip/xt_geoip_dl_maxmind.1
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
.TH xt_geoip_dl_maxmind 1 "2010-12-17" "xtables-addons" "xtables-addons"
|
||||||
|
.SH Name
|
||||||
|
.PP
|
||||||
|
xt_geoip_dl_maxmind \(em download MaxMind GeoIP database files
|
||||||
|
.SH Syntax
|
||||||
|
.PP
|
||||||
|
\fI/usr/libexec/xt_geoip/\fP\fBxt_geoip_dl_maxmind\fP [\fI licence-key file\fP]
|
||||||
|
.SH Description
|
||||||
|
.PP
|
||||||
|
Downloads the MaxMind GeoLite2 databases for IPv4 and IPv6 and unpacks them to
|
||||||
|
the current directory. The alternate \fBxt_geoip_dl\fP script can be
|
||||||
|
used for the DB-IP Country Lite databases.
|
||||||
|
.PP
|
||||||
|
Since the script is usually installed to the libexec directory of the
|
||||||
|
xtables-addons package and this is outside $PATH (on purpose), invoking the
|
||||||
|
script requires it to be called with a path.
|
||||||
|
.SH Options
|
||||||
|
.PP
|
||||||
|
None.
|
||||||
|
.SH See also
|
||||||
|
.PP
|
||||||
|
xt_geoip_build_maxmind(1)
|
@@ -1,95 +0,0 @@
|
|||||||
#!/usr/bin/perl
|
|
||||||
#
|
|
||||||
# Utility to query GeoIP database
|
|
||||||
# Copyright Philip Prindeville, 2018
|
|
||||||
#
|
|
||||||
use Getopt::Long;
|
|
||||||
use Socket qw(AF_INET AF_INET6 inet_ntop);
|
|
||||||
use warnings;
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
sub AF_INET_SIZE() { 4 }
|
|
||||||
sub AF_INET6_SIZE() { 16 }
|
|
||||||
|
|
||||||
my $target_dir = ".";
|
|
||||||
my $ipv4 = 0;
|
|
||||||
my $ipv6 = 0;
|
|
||||||
|
|
||||||
&Getopt::Long::Configure(qw(bundling));
|
|
||||||
&GetOptions(
|
|
||||||
"D=s" => \$target_dir,
|
|
||||||
"4" => \$ipv4,
|
|
||||||
"6" => \$ipv6,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!-d $target_dir) {
|
|
||||||
print STDERR "Target directory $target_dir does not exit.\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# if neither specified, assume both
|
|
||||||
if (! $ipv4 && ! $ipv6) {
|
|
||||||
$ipv4 = $ipv6 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach my $cc (@ARGV) {
|
|
||||||
if ($cc !~ m/^([a-z]{2}|a[12]|o1)$/i) {
|
|
||||||
print STDERR "Invalid country code '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $file = $target_dir . '/' . uc($cc) . '.iv4';
|
|
||||||
|
|
||||||
if (! -f $file) {
|
|
||||||
printf STDERR "Can't find data for country '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
my ($contents, $buffer, $bytes, $fh);
|
|
||||||
|
|
||||||
if ($ipv4) {
|
|
||||||
open($fh, '<', $file) || die "Couldn't open file for '$cc'\n";
|
|
||||||
|
|
||||||
binmode($fh);
|
|
||||||
|
|
||||||
while (($bytes = read($fh, $buffer, AF_INET_SIZE * 2)) == AF_INET_SIZE * 2) {
|
|
||||||
my ($start, $end) = unpack('a4a4', $buffer);
|
|
||||||
$start = inet_ntop(AF_INET, $start);
|
|
||||||
$end = inet_ntop(AF_INET, $end);
|
|
||||||
print $start, '-', $end, "\n";
|
|
||||||
}
|
|
||||||
close($fh);
|
|
||||||
if (! defined $bytes) {
|
|
||||||
printf STDERR "Error reading file for '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
} elsif ($bytes != 0) {
|
|
||||||
printf STDERR "Short read on file for '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
substr($file, -1) = '6';
|
|
||||||
|
|
||||||
if ($ipv6) {
|
|
||||||
open($fh, '<', $file) || die "Couldn't open file for '$cc'\n";
|
|
||||||
|
|
||||||
binmode($fh);
|
|
||||||
|
|
||||||
while (($bytes = read($fh, $buffer, AF_INET6_SIZE * 2)) == AF_INET6_SIZE * 2) {
|
|
||||||
my ($start, $end) = unpack('a16a16', $buffer);
|
|
||||||
$start = inet_ntop(AF_INET6, $start);
|
|
||||||
$end = inet_ntop(AF_INET6, $end);
|
|
||||||
print $start, '-', $end, "\n";
|
|
||||||
}
|
|
||||||
close($fh);
|
|
||||||
if (! defined $bytes) {
|
|
||||||
printf STDERR "Error reading file for '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
} elsif ($bytes != 0) {
|
|
||||||
printf STDERR "Short read on file for '$cc'\n";
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit 0;
|
|
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
#
|
#
|
||||||
# Utility to query GeoIP database
|
# Utility to query GeoIP database (.iv4/.iv6 files)
|
||||||
# Copyright Philip Prindeville, 2018
|
# Copyright Philip Prindeville, 2018
|
||||||
#
|
#
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
@@ -1,16 +1,16 @@
|
|||||||
.TH xt_geoip_fetch 1 "2020-04-30" "xtables-addons" "xtables-addons"
|
.TH xt_geoip_query 1 "2020-04-30" "xtables-addons" "xtables-addons"
|
||||||
.SH Name
|
.SH Name
|
||||||
.PP
|
.PP
|
||||||
xt_geoip_fetch \(em dump a country database to stdout
|
xt_geoip_query \(em dump a country database to stdout
|
||||||
.SH Syntax
|
.SH Syntax
|
||||||
.PP
|
.PP
|
||||||
\fBxt_geoip_fetch\fP [\fB\-D\fP
|
\fBxt_geoip_query\fP [\fB\-D\fP
|
||||||
\fIdatabase_dir\fP] [\fB-4\fP] [\fB-6\fP] \fIcc\fP [ \fIcc\fP ... ]
|
\fIdatabase_dir\fP] [\fB-4\fP] [\fB-6\fP] \fIcc\fP [ \fIcc\fP ... ]
|
||||||
.SH Description
|
.SH Description
|
||||||
.PP
|
.PP
|
||||||
xt_geoip_fetch unpacks a country's IPv4 or IPv6 databases and dumps
|
xt_geoip_query reads a country's IPv4 or IPv6 databases and dumps
|
||||||
them to standard output as a sorted, non-overlaping list of ranges (which
|
them to standard output as a sorted, non-overlapping list of ranges (which
|
||||||
is how they're represented in the database) suitable for browsing or
|
is how they are represented in the database), suitable for browsing or
|
||||||
further processing.
|
further processing.
|
||||||
.PP Options
|
.PP Options
|
||||||
.TP
|
.TP
|
||||||
@@ -29,7 +29,7 @@ The ISO-3166 country code names of the desired countries' databases.
|
|||||||
.PP
|
.PP
|
||||||
Shell command to dump the list of Swiss IPv6 address ranges:
|
Shell command to dump the list of Swiss IPv6 address ranges:
|
||||||
.PP
|
.PP
|
||||||
xt_geoip_fetch \-D /usr/share/xt_geoip \-6 ch
|
xt_geoip_query \-D /usr/share/xt_geoip \-6 ch
|
||||||
.SH See also
|
.SH See also
|
||||||
.PP
|
.PP
|
||||||
xt_geoip_build(1)
|
xt_geoip_build(1)
|
@@ -1,4 +1,4 @@
|
|||||||
.TH xtables-addons 8 "" "" "v3.12 (2020-11-19)"
|
.TH xtables-addons 8 "" "Caketime" "v3.15 (2021-02-05)"
|
||||||
.SH Name
|
.SH Name
|
||||||
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||||
.SH Targets
|
.SH Targets
|
||||||
|
Reference in New Issue
Block a user