当前位置:网站首页>Iptables target tproxy
Iptables target tproxy
2022-06-30 10:55:00 【redwingz】
TPROXY The target help information is as follows .
# iptables -j TPROXY -h
TPROXY target options:
--on-port port Redirect connection to port, or the original port if 0
--on-ip ip Optionally redirect to the given IP
--tproxy-mark value[/mask] Mark packets with the given value/mask
The following configuration , Set destination port 80 Message setting flag of 1, And send it to the local monitor 30080 The socket of .
# iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
--tproxy-mark 0x1/0x1 --on-port 30080
#
# iptables -t mangle -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
TPROXY tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
TPROXY redirect 0.0.0.0:30080 mark 0x1/0x1
The configuration is as follows IP Routing strategy , Mark as 1 Message of , Send it to the loopback equipment of the machine lo Handle , Local reception :
# ip rule add fwmark 1 lookup 100
# ip route add local 0.0.0.0/0 dev lo table 100
Application layer program , Socket interface needs to be set IP Layer options IP_TRANSPARENT(SOL_IP, IP_TRANSPARENT), To receive proxy messages .
TPROXY The goal is
function xt_register_targets Register target structure tproxy_tg_reg.
static struct xt_target tproxy_tg_reg[] __read_mostly = {
{
.name = "TPROXY",
.family = NFPROTO_IPV4,
.table = "mangle",
.target = tproxy_tg4_v1,
.revision = 1,
.targetsize = sizeof(struct xt_tproxy_target_info_v1),
.checkentry = tproxy_tg4_check,
.hooks = 1 << NF_INET_PRE_ROUTING,
.me = THIS_MODULE,
},
static int __init tproxy_tg_init(void)
{
return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg));
The configuration check function is as follows , about IPv4 agreement , Enable the message reorganization function , Transparent proxy only supports TCP and UDP agreement .
static int tproxy_tg4_check(const struct xt_tgchk_param *par)
{
const struct ipt_ip *i = par->entryinfo;
int err;
err = nf_defrag_ipv4_enable(par->net);
if (err)
return err;
if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
&& !(i->invflags & IPT_INV_PROTO))
return 0;
pr_info_ratelimited("Can be used only with -p tcp or -p udp\n");
return -EINVAL;
The target processing function is as follows ,tproxy_tg4 The parameters used are as shown above :(TPROXY redirect 0.0.0.0:30080 mark 0x1/0x1)
static unsigned int
tproxy_tg4_v1(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct xt_tproxy_target_info_v1 *tgi = par->targinfo;
return tproxy_tg4(xt_net(par), skb, tgi->laddr.ip, tgi->lport,
tgi->mark_mask, tgi->mark_value);
First , Check whether the message belongs to the socket interface after connection establishment , secondly , Identify local IP Address and port number , If TPROXY The configured local address is zero , Use... On the interface that receives the packet IP Address as local address . If , The configured local port is zero , Use the destination port in the message .
static unsigned int
tproxy_tg4(struct net *net, struct sk_buff *skb, __be32 laddr, __be16 lport,
u_int32_t mark_mask, u_int32_t mark_value)
{
const struct iphdr *iph = ip_hdr(skb);
struct udphdr _hdr, *hp;
struct sock *sk;
hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
if (hp == NULL)
return NF_DROP;
/* check if there's an ongoing connection on the packet
* addresses, this happens if the redirect already happened
* and the current packet belongs to an already established
* connection */
sk = nf_tproxy_get_sock_v4(net, skb, iph->protocol,
iph->saddr, iph->daddr,
hp->source, hp->dest,
skb->dev, NF_TPROXY_LOOKUP_ESTABLISHED);
laddr = nf_tproxy_laddr4(skb, laddr, iph->daddr);
if (!lport)
lport = hp->dest;
If the socket with connection establishment status is not found above , Find the socket that listens to the status .
/* UDP has no TCP_TIME_WAIT state, so we never enter here */
if (sk && sk->sk_state == TCP_TIME_WAIT)
/* reopening a TIME_WAIT connection needs special handling */
sk = nf_tproxy_handle_time_wait4(net, skb, laddr, lport, sk);
else if (!sk)
/* no, there's no established connection, check if
* there's a listener on the redirected addr/port */
sk = nf_tproxy_get_sock_v4(net, skb, iph->protocol,
iph->saddr, laddr,
hp->source, lport,
skb->dev, NF_TPROXY_LOOKUP_LISTENER);
If the socket found has the Transparency option set , Assign the socket to skb. otherwise , Discard message .
/* NOTE: assign_sock consumes our sk reference */
if (sk && nf_tproxy_sk_is_transparent(sk)) {
/* This should be in a separate target, but we don't do multiple
targets on the same rule yet */
skb->mark = (skb->mark & ~mark_mask) ^ mark_value;
pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
iph->protocol, &iph->daddr, ntohs(hp->dest),
&laddr, ntohs(lport), skb->mark);
nf_tproxy_assign_sock(skb, sk);
return NF_ACCEPT;
}
pr_debug("no socket, dropping: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n",
iph->protocol, &iph->saddr, ntohs(hp->source),
&iph->daddr, ntohs(hp->dest), skb->mark);
return NF_DROP;
TCP Socket connector
about TCP agreement , In general, in the function __inet_lookup_skb Find sockets in .
int tcp_v4_rcv(struct sk_buff *skb)
{
th = (const struct tcphdr *)skb->data;
iph = ip_hdr(skb);
lookup:
sk = __inet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source,
th->dest, sdif, &refcounted);
however , If skb There are already sockets available in the structure , Return to this socket (TPROXY Assignment in ).
static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
struct sk_buff *skb, int doff,
const __be16 sport, const __be16 dport,
const int sdif, bool *refcounted)
{
struct sock *sk = skb_steal_sock(skb, refcounted);
const struct iphdr *iph = ip_hdr(skb);
if (sk)
return sk;
about TIME_WAIT State of TCP Socket connector , If the received message is a SYN message , Find out whether there is a socket that listens , Give priority to the use of monitoring sockets .
struct sock *
nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
__be32 laddr, __be16 lport, struct sock *sk)
{
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr _hdr, *hp;
hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
if (hp == NULL) {
inet_twsk_put(inet_twsk(sk));
return NULL;
}
if (hp->syn && !hp->rst && !hp->ack && !hp->fin) {
/* SYN to a TIME_WAIT socket, we'd rather redirect it
* to a listener socket if there's one */
struct sock *sk2;
sk2 = nf_tproxy_get_sock_v4(net, skb, iph->protocol,
iph->saddr, laddr ? laddr : iph->daddr,
hp->source, lport ? lport : hp->dest,
skb->dev, NF_TPROXY_LOOKUP_LISTENER);
if (sk2) {
inet_twsk_deschedule_put(inet_twsk(sk));
sk = sk2;
}
}
return sk;
UDP Socket connector
about UDP agreement , If skb The socket interface structure is not empty , Use this socket (TPROXY Assignment in ).
int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
int proto)
{
sk = skb_steal_sock(skb, &refcounted);
if (sk) {
struct dst_entry *dst = skb_dst(skb);
int ret;
if (unlikely(sk->sk_rx_dst != dst))
udp_sk_rx_dst_set(sk, dst);
ret = udp_unicast_rcv_skb(sk, skb, uh);
if (refcounted)
sock_put(sk);
return ret;
}
Kernel version 5.10
边栏推荐
- 无心剑中译狄金森《灵魂择其伴侣》
- 电商两位大佬花边新闻刷屏,代表电商回归正常,将有利于实体经济
- DQN笔记
- 内存逃逸分析
- JS FAQs
- Pycharm项目使用pyinstalle打包过程中问题及解决方案
- SGD有多种改进的形式,为什么大多数论文中仍然用SGD?
- MATLAB image histogram equalization, namely spatial filtering
- Skill sorting [email protected]+ Alibaba cloud +nbiot+dht11+bh1750+ soil moisture sensor +oled
- [rust daily] the first rust monthly magazine on January 22, 2021 invites everyone to participate
猜你喜欢

电化学氧气传感器寿命、工作原理及应用介绍

吴恩达2022机器学习专项课测评来了!

Auto SEG loss: automatic loss function design
![[deep learning] common methods for deep learning to detect small targets](/img/c6/8f0549864992a1554397bad16dad4d.jpg)
[deep learning] common methods for deep learning to detect small targets

DQN笔记

在IPhone12的推理延迟仅为1.6 ms!Snap等详析Transformer结构延迟,并用NAS搜出移动设备的高效网络结构...

无心剑中译狄金森《灵魂择其伴侣》
[email protected] intelligent instrument teaching aids based on 51 series single chip microcomputer"/>Skill combing [email protected] intelligent instrument teaching aids based on 51 series single chip microcomputer

matplotlib 笔记: contourf & contour

Go zero micro Service Practice Series (VIII. How to handle tens of thousands of order requests per second)
随机推荐
国产自研系统的用户突破4亿,打破美国企业的垄断,谷歌后悔不迭
CSDN blog operation team 2022 H1 summary
Review of mathematical knowledge: curve integral of the second type
SGD has many improved forms. Why do most papers still use SGD?
Skill sorting [email protected]+ Alibaba cloud +nbiot+dht11+bh1750+ soil moisture sensor +oled
深潜Kotlin协程(十八):冷热数据流
The precision problem of depth texture in unity shader - stepping pit - BRP pipeline (there is no solution, it is recommended to replace URP)
Qt之实现动效导航栏
前嗅ForeSpider教程:抽取数据
[rust weekly database] num bigint - large integer
Gd32 RT thread DAC driver function
The intelligent DNA molecular nano robot model is coming
敏捷开发: 超级易用水桶估计系统
Pytorch notes torch nn. BatchNorm1d
数据库什么时候需要使用索引【杭州多测师】【杭州多测师_王sir】
Pycharm项目使用pyinstalle打包过程中问题及解决方案
[proteus simulation] Arduino uno led simulated traffic light
LeetCode Algorithm 86. 分隔链表
LVGL 8.2 Simple Colorwheel
LVGL 8.2图片缩放及旋转