How to record the packets after iptables? - iptables

I want to record the packets (using tcpdump) after iptables, but it seems that tcpdump will record all the packets. I don't want the packet dropped by iptables.
Is there any way to
record the packets after iptables? or
output the packets (processing by iptables) into pcap/log file?
Thanks.

Tcpdump acts before iptables for inbound traffic, but you can use iptables "NFLOG" extension to reach your goal: http://ipset.netfilter.org/iptables-extensions.man.html#lbDI
Using "NFLOG" destination you can log desired packets to userspace application, and that's where tcpdump belongs (you can also assign traffic to a specific group and then tell tcpdump to listen from it).
Webserver (very basic) example, let's pretend you are accepting http/https traffic and dropping ssh:
#BASIC RULES
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
#NFLOG REDIRECT ONLY HTTP TRAFFIC
iptables -A INPUT -p tcp --dport 80 -j NFLOG
#TCPDUMP ONLY ON MATCHED TRAFFIC (=HTTP)
tcpdump -i nflog

Related

Can iptables be used to prevent internal connection?

I can set iptables rules to prevent external connection. But can we use iptables to prevent internal connection? For example, I have set iptables to prevent port 5555 port on my machine, but my local APP can still connect with 5555 when running on my machine.
Yes you can block it using iptables.
iptables -A INPUT -d 127.0.0.1 -p tcp --dport 5555 -j DROP
With this command you'll not be able to connect from your own host to your own service. Then you can remove the rule using the opposite to -A append which is -D delete:
iptables -D INPUT -d 127.0.0.1 -p tcp --dport 5555 -j DROP
Hope it helps.
Depends upon how you are blocking the port 5555, if you have a specific INPUT rule with interface and source and/or destination addresses it would match only those. In your case, you could modify your rule to just match tcp destination port 5555 and it will block all packets to tcp destination port 5555. for eg:
iptables -t filter -I INPUT -p tcp --dport 5555 -j DROP
If you just want to block your internal apps and not touch your existing iptables rule then use the incoming interface as lo for eg:
iptables -t filter -I INPUT -i lo -p tcp --dport 5555 -j DROP
Note: If you are using destination ip then use the entire loopback address range rather than just 127.0.0.1 for eg:
iptables -t filter -I INPUT -d 127.0.0.0/8 -p tcp --dport 5555 -j DROP
Before you do any changes you can instead of -j DROP action use -j LOG action to log and confirm the tcp connections this rule will match. You could also skip the action part without specifying the -j option and check how many packets would match your rule with iptables -t filter -L -n -v without causing any harm.

IP Tables - Need understanding on a rule

iptables -A FORWARD -s 0/0 -i eth0 -d 192.168.1.58 -o eth1 -p TCP \ --sport 1024:65535 --dport 80 -j ACCEPT
This rule is applied to packets that are traversing the firewall. It ACCEPTs (allows) packets that match the following properties:
incoming interface is eth0
outgoing interface is eth1
any source IP
destination IP is 192.168.1.58
protocol is TCP
source port is between 1024 and 65535
destination port is 80 (HTTP)
In the future, questions such as this are better suited towards SuperUser or ServerFault rather than StackOverflow.

Redirecting from outgoing loopback traffic - is it possible?

I have 2 kinds of proxies in my local machine : stunnel and TOR-VPN.
stunnel is listening on port 6666
TOR-VPN is listening on port 9040
I want to get web traffic to go to stunnel first and the output traffic of stunnel go to tor-vpn. This needs double redirecting. is it possible to do it with iptables? I mean by using "table nat chain OUTPUT".
Because as far as I know "table nat chain OUTPUT" cant be called twice.
web traffic = browser listening on 127.0.0.1:6666
these are my rules:
iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-ports 6666
iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner bob -m tcp -j
REDIRECT --to-ports 9040
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner bob -m udp
--dport 53 -j REDIRECT --to-ports 53
iptables -t filter -A OUTPUT -p tcp --dport 6666 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -m owner --uid-owner bob -m tcp
--dport 9040 -j ACCEPT
iptables -t filter -A OUTPUT -p udp -m owner --uid-owner bob -m udp
--dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -m owner --uid-owner bob -j DROP
the above rules make stunnel work independently from TOR/VPN.
i mean when browser is set with proxy, no traffic will go through TOR/VPN but if i turn off the proxy in browser, all traffic will go through TOR/VPN.
now i want to let browser have the proxy on and all web traffic go to stunnel first, but outgoing stunnel traffic(outgoing loopback traffic) redirects to TOR/VPN(127.0.0.1:9040)
is it possible ? how can i do that? somehow i mean double redirecting inside system.
Policy of all tables is ACCEPT
Checking that this is what you mean :
You have stunnel bound to port 6666 (localhost:6666) and you have tor bound to 9040 (localhost:9040). You want it so your web traffic will go THROUGH stunnel (so destination is localhost:6666) but the OUTBOUND traffic FROM stunnel (with inbound traffic originally from your client redirected to stunnel) should be DESTINED to tor (localhost:9040) ? Is this correct ?
If so, and I am thinking clearly enough (it is just 7:00 and I've been awake far too many hours for a difficult night), this is indeed possible (the reverse is, too). You need to masquerade the destination address (and indeed port) based on the source (address and port (you don't have to specify both, I might add)). Something like this:
iptables -t nat -I PREROUTING -p tcp --sport 6666 -j DNAT --to-destination 9040
If this is not what you mean (or alternatively I made a typo, am not clear headed or being an idiot in some way (in all cases showing myself to be a user as everyone is!), if any it is probably the latter) then please respond. I'll see about enabling email notification so that I see the response. If I don't, however, I apologise in advance.
As an aside: unless you have a final rule in each CHAIN (not table, just as an fyi: a table is filter, nat (which I specify in the above and indeed it is necessary), etc. and CHAIN is INPUT, OUTPUT, FORWARD and others created by the option -N) you shouldn't have -P ACCEPT ('that which is not explicitly permitted is forbidden' and similar wording - i.e. have DROP). The exception is perhaps OUTPUT (but depends on what you need, in the end). However, when dealing with interface 'lo' you'll want to ACCEPT all traffic always, in any case (i.e. specify -i lo and -o lo, depending on chain, and jump to ACCEPT). Of course, maybe you're behind another device but still best practise to not accept anything and everything! (I should also state that you have different chains per table so yes you can specify different tables but the policy is for the chain IN that table)
Edit: something else: no, you don't have to deal with SNAT when you want DNAT and the reverse is true. Anything to the contrary is a misunderstanding. The reason is you're masquerading the CONNECTION. As the man page shows:
It specifies that the destination address of the
packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined.
Edit:
If I understand you (now) you actually have two interfaces involved. Or more specifically you need the following:
You have a service you want encrypted. This is tor. Now, you're using stunnel to do this. To this end you want stunnel to forward traffic to tor. Is this right? If yes, then know that stunnel has the following directives (I actually use similar for something else). Here's a mock setup of a service.
[tor]
accept = 6666
connect = 9040
In addition, just as a note: connect can also be a remote address (remote address implies an external address (with port) or even a certain interface (by IP and also with port) on the system (I use external in the sense of you specify ip and port rather than just a port). Furthermore, accept can specify address (with same rules: ip before the port (except that it is obviously on the local machine so no external IP)). You could explain it, perhaps, as stunnel is where the service would bind to except that the service is stunnel and the service it is encrypting is elsewhere (shortly: the bind(2) call allows specific IP or all IPs on the system, and you're basically configuring stunnel to do this).
(And yes, you're right: the sport should have been dport.)
IF this is not what you need then I do not understand all variables. In that case, if you can elaborate on which interfaces (this includes ports and which service per interface) are involved as well as clients involved (and where they send). Because it is a lot more helpful if others know EXACTLY what you need than infer certain parts. Makes it much easier to solve a problem if you know what the problem is entirely. Maybe I've been dense and I should put together it all (and I admit sleep problems - which I have for a long, long time - does not help that, but...) I haven't, I think.
I found the answer by myself. in my first post, i said something that was completely wrong and because of that, i could not do double redirecting.
i said:
Because as far as I know "table nat chain OUTPUT" cant be called twice
it is wrong and "table nat chain OUTPUT" can be called twice. i dont know what exactly i did 2 months ago that thought "table nat chain OUTPUT" cant be called twice.
this is the tables and chains order when using some services on loopback interface or not:
Without having any services on loopback:
Generated packets on local machine -> nat(OUTPUT) -> filter(OUTPUT) -> wlan(ethernet) interface
With having some services on loopback:
Generated packets on local machine -> nat(OUTPUT) -> filter(OUTPUT) -> loopback interface -> nat(OUTPUT) -> filter(OUTPUT) -> wlan(ethernet) interface
these are my rules to solve the problem:
iptables -t nat -A OUTPUT -p tcp -m tcp --dport 6666 -j REDIRECT --to-ports 6666
iptables -t nat -A OUTPUT -p tcp -m owner --uid-owner bob -m tcp -j REDIRECT --to-ports 9040
iptables -t nat -A OUTPUT -p udp -m owner --uid-owner bob -m udp --dport 53 -j REDIRECT --to-ports 53
iptables -t nat -A OUTPUT -d "StunnelServerIp" -o wlan0 -p tcp -j REDIRECT --to-ports 9040
iptables -t filter -A OUTPUT -p tcp -m owner --uid-owner bob -m tcp --dport 9040 -j ACCEPT
iptables -t filter -A OUTPUT -p udp -m owner --uid-owner bob -m udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -m tcp --dport 6666 -j ACCEPT
iptables -t filter -A OUTPUT -m owner --uid-owner bob -j DROP

IPTables forward traffic without hiding source IP

I am trying to setup a cloud server as a gateway, which forwards all traffic to my second cloud server. The problem is that the destination server (2nd cloud) only sees the IP address of the first cloud server.
Is it possible to keep the source IP so it would show the IP address of the one connecting to the first cloud server. I have tried removing MASQUERADE, but the connection between cloud #1 -> cloud #2 did not work properly anymore.
-A FORWARD -p tcp -m tcp --dport 25565 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 25565 -j DNAT --to-destination DESTINATIONIP:PORT
-A POSTROUTING -j MASQUERADE
It works with this setup, but does not show the source IP. Have you got any idea on how to not hide the IP that is connecting to the first cloud server?
Thanks
cloud 1 and 2 need to be in same network, a VPN is fine
on cloud1:
-A FORWARD -p tcp -m tcp --dport 25565 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 25565 -j DNAT --to-destination DESTINATIONIP:PORT
-A POSTROUTING -j MASQUERADE
on cloud2, we mark the desired packet with 1, eth0 is the default gateway:
iptables -t mangle -A OUTPUT -o eth0 -p tcp --sport 25565 -j MARK --set-mark 1
you need to manipulate the routing table on cloud2:
edit /etc/iproute2/rt_tables, add the line
1 http
here the manipulation, tun0 is the vpn interface on cloud2:
ip route add default via ip_vpn_cloud1 dev tun0 table http
ip rule add from all fwmark 1 table http
be sure that net.ipv4.conf.all.rp_filter and net.ipv4.conf.default.rp_filter are set to 1 in /etc/sysctl.conf
With -A POSTROUTING -j MASQUERADE all outgoing forwarded packets will have the source IP of the corresponding outgoing interface.
You should be more specific on the packets you masquerade/SNAT.

iptables allow whm mail port 25

Trying to understand iptables (I have cPanel installed on VPS) and having a little play so may sound like a silly question what I am doing.
I have copied the default iptables config to backup (in case goes wrong to restore) and created custom iptables config (/etc/sysconfig/iptables) were I DROP INPUT/OUTPUT/FORWARDING (so everything).
I then managed to get all the ports I want access to required working (incoming/outgoing HTTP/s/SSH/FTP etc) apart from emails (:25). I am using Roundcube and using the below config for emails but emails can not be sent/received on my server (works if I restore default config (ACCEPT everything) so apart from port :25 is there any other ports I need to allow access to for mail to be sent knowing everything has been dropped?). I am using below config for email in my custom (/etc/sysconfig/iptables):-
-A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
IP is a bidirectional communication, when you receive a mail, packets are sent on your server on port 25, and you will send response packet on a arbitrary allocated port number (determined during connection establishment).
So, common rule on iptables are :
Accepting packet on input from a specified port (25 for mail) whatever the state of connection
-A INPUT -p tcp --dport 25 -j ACCEPT
Accepting to send back packets for all established connection whatever the destination port.-A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
Now, if you want to send mail to a server, you have to allow packet to go out to port 25 and allow incoming all established connection.
-A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT
Another idea , will be to log packets that should be dropped.
put log line a the end of all chain's rules.
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT PACKET DROPPED "
iptables -A OUTPUT -p tcp -j LOG --log-prefix "OUTPUT PACKET DROPPED "
With that, you will see in /var/log/message (or with dmesg) a line for each packet reaching the end of chain's rule and beeing dropped.