We have been using CSF on a virtualized (OpenVZ) environment successfully for a while combining venet and bridged interfaces so we can use public IPs + local addressed virtual systems.
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.100 0.0.0.0 255.255.255.255 UH 0 0 0 venet0
xxx.xxx.xxx.24 0.0.0.0 255.255.255.255 UH 0 0 0 venet0
xxx.xxx.xxx.0 0.0.0.0 255.255.255.0 U 0 0 0 vmbr0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 vmbr10
0.0.0.0 xxx.xxx.xxx.254 0.0.0.0 UG 0 0 0 vmbr0
We route traffic of "local" ips via an iptables rule:
iptables -t nat -A POSTROUTING -s "10.0.0.0/24" -o vmbr0 -j MASQUERADE
/proc/sys/net/ipv4/ip_forward value is obvioyly set to 1
The host and venet networked machines run their own CSF installation that creates all the firewall rules for this setup which includes the possibility to create "redirects" to internal IPs.
With this we can open specific ports on the host IP that are served by the local internal virtual machines on local based network. Among the long list of firewall rules that CSF creates are:
Chain PREROUTING (policy ACCEPT 53M packets, 15G bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DNAT tcp -- !lo * 0.0.0.0/0 XXX.XXX.XXX.184 tcp dpt:5100 to:10.0.0.100:5000
Chain POSTROUTING (policy ACCEPT 9700K packets, 615M bytes)
num pkts bytes target prot opt in out source destination
3 0 0 SNAT tcp -- * !lo 0.0.0.0/0 10.0.0.100 to:XXX.XXX.XXX.184
8 10 600 MASQUERADE all -- * vmbr0 10.0.0.0/24 0.0.0.0/0
The redirect feature on CSF firewall works but the IP reported is the host one, not the originating IP so we can not limit it with another CSF instance (or simple firewall rule) on the destination virtual system. We understand that being on PREROUTING they can not be limited on on the host CSF either.
The CSF readme actually states "All redirections to another IP address will always appear on the destination server with the source of this server, not the originating IP address." so this is a standard feature.
CSF supports a postrules.sh file where we could include the NAT rules manually but we are unsure if with IPTABLES SNAT and/or DNAT it is possible to pass the "real" source IP to the destination of the NAT IP.
The only way to see the "real" source IP, you mentioned, at the destination is to avoid Natting or Masquerading it. Remember, SNAT and DNAT stand for Source and Destination Network TRANSLATION, respectively, so once the packet traverses the Natting rules, the source/destination addresses are "changed" for good. You can't retrieve them at the destination.
Question:
Answer:
Yes, it is possible, and here's how to do it if you're using CSF. Don't rely on CSF's redirect feature, i.e. having a line similar to the following in
/etc/csf/csf.redirect
:Instead, put the following
iptables
commands in/etc/csf/csfpost.sh
:Test:
Explanation:
This line redirects TCP traffic coming in on the external interface on port
2222
to the internal address10.0.0.100
on port22
./sbin/iptables
the fulliptables
executable is required.--table nat
working on the nat (Network Address Translation) table.--append PREROUTING
append this rule after all existing rules in thePREROUTING
chain.--in-interface vmbr0
catch all traffic comin in on thevmbr0
interface.--protocol tcp
catch only tcp traffic.--match tcp
use the tcp module.--dport 2222
catch only traffic directed to port2222
.--jump DNAT
perform a Destination Network Address Translation.--to-destination 10.0.0.100:22
change the destination address to10.0.0.100
and the destination port to22
.This line allows to not skip all of CSF's filtering just because we are redirecting.
/sbin/iptables
the fulliptables
executable is required.--insert FORWARD
insert this rule before existing rules in theFORWARD
chain. This is where redirected packets are going, as opposed e.g. to theINPUT
chain.--in-interface vmbr0
match traffic coming in on thevmbr0
interface.--out-interface vmbr10
match traffic going out from thevmbr0
interface as an effect of redirection.--destination 10.0.0.0/24
match only traffic destined to (redirected to) the internal network.--jump LOCALINPUT
go through theLOCALINPUT
chain. This is where CSF performs all the good filtering it is known for, keeping banned and blacklisted IPs from reaching the system. With this rule, we extend CSF's filtering to all hosts on the internal network (as opposed to just traffic destined for the host where CSF is running).This line passes all remaining forwarded traffic to the internal hosts.
/sbin/iptables
the fulliptables
executable is required.--insert FORWARD
insert this rule before existing rules in theFORWARD
chain. This rule will be evaluated after all the filering is performed in theLOCALINPUT
chain.--in-interface vmbr0
match traffic coming in on thevmbr0
interface.--out-interface vmbr10
match traffic going out from thevmbr0
interface as an effect of redirection.--destination 10.0.0.0/24
match only traffic destined to (redirected to) the internal network.--jump ACCEPT
after CSF has performed all its filtering (in theLOCALINPUT
chain), we want remaining packets to beACCEPT
ed.