I have a problem setting up a DNAT in POSTROUTING (I really need it for a project).
In the beginning, I tried to set it using iptables with this command:
iptables -t nat -A POSTROUTING -p icmp -d 30.0.0.1 -j DNAT --to-destination 40.0.0.1 but iptables gave me this error iptables v1.8.7 (nf_tables): RULE_APPEND failed (Invalid argument): rule in chain POSTROUTING.
Then I read on the iptables man page that is not possible to do what I'm trying to do.
After that, I tried to do the same thing using nftables using those commands:
nft add table nat
nft 'add chain nat postrouting { type nat hook postrouting priority -100; }'
nft add rule nat postrouting oif wg-1to2 dnat to 40.0.0.1.
But nftables returned me this error Error: Could not process rule: Operation not supported.
I don't think it is possible to set a POSTROUTING DNAT with nftables.
Am I wrong or a, I making some mistakes?
If it is not possible, why? Is it just something that is not implemented?
Are there are some technical problems that make it impossible to be implemented?
How would you solve this problem?
Thanks in advice
Francesco,
to my understanding, you cannot do DNAT in POSTROUTING.
The reason is that in the (kernel) routing/forwarding code, several parameters get adjusted based on the destination contained in your packets (e.g., next hop, interface where this packet has to be sent from, MAC address to reach the next hop).
If you do DNAT, hence you change the destination address in your packet, the above parameters may become invalid, hence you may need to traverse the routing/forwarding code again. However, given the position of the POSTROUTING hook in the Linux kernel, this is no longer possible.
For instance, SNAT is perfectly supported instead.
A possible solution to this problem is to write an eBPF program that does DNAT and adjusts the above parameters.
Hope this helps.
Related
I have a server (openvpn) which is not multithreaded and hence does not take advantage of the multiple cores in the box. I'm trying to solve the problem by running multiple servers, each on a different port, e.g. 127.0.0.1:8000, 127.0.0.1:8001, ... then load balancing the exterior 1194 port based on the source IP -- openvpn uses UDP but all packets for a client must arrive at the same server.
Issue I'm running into is how to load balance. I tried IPVS, but it seems like it doesn't work with servers on the same host. Then tried nginx's new udp feature, but again no dice. Any ideas on how to achieve this?
I discovered that plain old iptables can create such a load balancer, using the HMARK target extension (see man 8 iptables-extensions).
Essentially the HMARK target can mark a packet based on a hash of specific IP tuple parameters, source IP and source port in my case, as these will be unique per client, even behind a NAT. Then I can route the packets to the appropriate localhost server based on the mark:
iptables -A PREROUTING -t mangle -p udp --dport 1194 -j HMARK \
--hmark-tuple src,sport --hmark-mod 2 \
--hmark-rnd 0xcafeface --hmark-offset 0x8000
iptables -A PREROUTING -t nat -p udp -m mark --mark 0x8000 \
-j DNAT --to-destination 127.0.0.1:8000
iptables -A PREROUTING -t nat -p udp -m mark --mark 0x8001 \
-j DNAT --to-destination 127.0.0.1:8001
Remember to enable routing packets to localhost:
sysctl -w net.ipv4.conf.eth0.route_localnet=1
I have a requirement in which need to block certain processes to consume network data using VPN interface ( tun0).
physical interface(cellular data) -> tun0- >user space program->physical interface-> destination.
pls correct me if i am wrong , the above way the traffic flows though when VPN is enabled.
so if i want to block one particular process network packet not to forwared to tun0 interface, i have applied the iptable rules for both the physical interface and the tun0 interface. still the application is able to use the network data using the tun0 interface.
is there a way to block the traffic at tun0 interface?
dont know which rules you set but maybe this fix
(allow only tun0, reject others)
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -A INPUT -i ! tun0 -j REJECT
iptables -A OUTPUT -o ! tun0 -j REJECT
I have two tomcat instances running on ports A and B. I would like all traffic on port C to be forward to A or B, ideally with a simple command and minimal configuration.
Is there a simple TCP switcher that can change the traffic like that ?
UPDATE: changing from ports A to B manually (command line for example) would be ok.
iptables offer the PREROUTING specifier for that:
iptables -t nat -A PREROUTING -p tcp --dport <C> -j REDIRECT --to-port <A>
Here <C> and <A> obviously refer to your ports.
How to write IPTable rules such that the administrator on 128.238.66.2 has ssh access to the firewall and no one else is allowed access?
Is it like: iptables –A INPUT –s 128.238.66.2 –j ACCEPT?
Try like this (please be aware that if the IP is wrong, you're locked out):
iptables -A INPUT -p tcp --dport ssh -j REJECT
iptables -A INPUT -p tcp -s 128.238.66.2 --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport ssh -m state --state ESTABLISHED -j ACCEPT
When we say about iptable it is that it bounds with Kernel. The function of iptable is for Setting_Up Firewall.
And to understand its basics you should understand it in, from ground level rather knocking with your sequence of absurd commands as you end-up scribbling & scratching head. Following step by step standard instruction will not be scenario always. SO, lets understand it.
There are three level segregation when we talk about iptable.
Level-1: Rule
Level-2: Chain
Level-3: Table
Lets see one by one now,
Rules are-> ACCEPT, DROP, QUEUE, RETURN
Chains are-> Input, Output, Forward, Pre Routing, Post Routing
Tables are-> Filter Table (Default), NAT Table, RAW Table, Mangle Table
Coming Next Firewalls by generations of improvement can be said like,
1) Packet Filtering Firewall
2) Stateful Firewall
3) Application Layer Firewall
4) Proxies Firewall.
Here is a little picture
Asterisk eth1 10.254.254.2/28------------- Many Good Guys
eth1:1 192.168.83.5/32----------- 192.168.59.3 Bad Guy Peer
I have an Asterisk which is connected with several peers. Some of them are connected through
eth1 and one the badest through alias eth1:1.
Then my asterisk send invite to peers it goes with the eth1 source. So for the bad guy I need to change my source ip to 192.168.83.5 As far as I know it can be done with iptables.
So I tried the rule
iptables -t nat -A POSTROUTING -s 10.254.254.2 -d 192.168.59.3 -j SNAT
--to 192.168.83.5
nothing happens.
When I log I can see send packets in INPUT and OUTPUT chains with :
iptables -t filter -A OUTPUT -o eth1 -s 10.254.254.2 -d 192.168.59.3
-j LOG --log-level 7 --log-prefix "OUTPUT"
iptables -t filter -A INPUT-i eth1 -s 192.168.59.3 -d 192.168.83.5 -j
LOG --log-level 7 --log-prefix "OUTPUT"
but I don’t see any in POSTROUTING chain with:
iptables -t nat -A POSTROUTING -s 10.254.254.2 -d 192.168.59.3 -j LOG
--log-level 7 --log-prefix "POSTROUTING"
That is I have nothing to SNAT(((
At the same time the traffic from other peers is visible in POSTROUTING log. What can it be?
Any thoughts, wishes, kicks would be very appreciated!
The solution has been found!!
I didn' t find a way to make my iptables work. But know i know how to do it without iptables at all.
So generally speaking my task was to modify|mask|replace my source ip of eth1 with eth1:1 ip.
By the way i use CentOS 5.8
And there is a command:
ip route add
which gives you ability to point scr address unlike the route command.
so
ip route add 192.168.59.3/32 via 10.254.254.1 dev eth1 src
192.168.83.5
is doing just what i need.
Thank you for attention!
That will not work. Reason is simple, asterisk will set in packet source addres=address of eth1.
You can start enother asterisk same host(with other config dir). I am sorry, i not know other simple variants.