当前位置:网站首页>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
边栏推荐
- Google 辟谣放弃 TensorFlow,它还活着!
- Mysql database foundation: TCL transaction control language
- 内存逃逸分析
- Qt之实现动效导航栏
- MATLAB image histogram equalization, namely spatial filtering
- Agile Development: super easy to use bucket estimation system
- [rust weekly database] num bigint - large integer
- 历史上的今天:微软收购 PowerPoint 开发商;SGI 和 MIPS 合并
- 国产自研系统的用户突破4亿,打破美国企业的垄断,谷歌后悔不迭
- [STL source code analysis] iterator
猜你喜欢
[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

软件测试工程师面试基础题(应届生和测试小菜必备)最基础的面试题

ArrayList and sequence table

List introduction

煥發青春的戴爾和蘋果夾擊,兩大老牌PC企業極速衰敗

Pytorch notes torch nn. BatchNorm1d

国产自研系统的用户突破4亿,打破美国企业的垄断,谷歌后悔不迭
![[机缘参悟-34]:光锥之内皆命运](/img/3e/9f5630ba382df7f7ce00705445cef8.jpg)
[机缘参悟-34]:光锥之内皆命运

微信推出图片大爆炸功能;苹果自研 5G 芯片或已失败;微软解决导致 Edge 停止响应的 bug|极客头条...

Q-Learning笔记
随机推荐
LVGL 8.2 menu from a drop-down list
Skill sorting [email protected]+adxl345+ Motor vibration + serial port output
iptables目标TPROXY
List introduction
LVGL 8.2 Simple Drop down list
nvm、nrm、npx使用(安装、基本命令、参数、curl、wget)
我们公司使用 7 年的这套通用解决方案,打通了几十个系统,稳的一批!
Retest the cloud native database performance: polardb is still the strongest, while tdsql-c and gaussdb have little change
[STL source code analysis] iterator
电化学氧气传感器寿命、工作原理及应用介绍
Typescript – classes in Es5, inheritance, static methods
Rejuvenated Dell and apple hit each other, and the two old PC enterprises declined rapidly
Matplotlib notes: contour & Contour
What is erdma as illustrated by Coptic cartoon?
透过华为军团看科技之变(五):智慧园区
LVGL 8.2图片缩放及旋转
ionic4 ion-reorder-group组件拖拽改变item顺序
Migrate full RT thread to gd32f4xx (detailed)
腾讯云数据库工程师能力认证重磅推出,各界共话人才培养难题
时间复杂度与空间复杂度