Get the result of a command as a variable in salt stack to modify iptables - iptables

I'm trying to put a new rule into iptables. What I would like is to put the rule into the penultimate line number (ie just before the DENY ALL statement). eg.
[vagrant#controller ~]$ sudo iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
2 ACCEPT icmp -- anywhere anywhere
3 ACCEPT all -- anywhere anywhere
4 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
5 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
then,
sudo iptables -I INPUT 5 -t filter -d 192.168.33.10 -m state --state NEW -j ACCEPT
would be:
[vagrant#controller ~]$ sudo iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
2 ACCEPT icmp -- anywhere anywhere
3 ACCEPT all -- anywhere anywhere
4 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
5 ACCEPT all -- anywhere 192.168.33.10 state NEW
6 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
the issue is that I can not figure out how I can automate this with salt without explicitly knowing what the last line number is? Is there a way of running a command in salt stack and use the result of that command as a variable for the jinja template?
sudo iptables -L INPUT --line-numbers | tail -n1 | awk '{print $1}'

I'm not aware of any simple way to do this the way its described above. Some of the work-arounds that come to mind:
Define the last rule such that it depends on (i.e. requires) the one you need to insert. Salt would then make sure that they are in the right order.
Create an additional iptables chain. Insert a jump to the new chain somewhere into the original config, then alter the rules in the chain as needed. This gives you a lot of flexibility.
Write a shell-script which does what you want and call it with cmd.run. Quite inelegant but requires fewer changes to other parts of the config.
Neither of those options is perfect and may not suit your use-case. However, combining the first to methods will get you pretty far and also result in an over all cleaner setup.

Related

Iptables masquerade not working on Debian VM

I have a VM in VirtualBox with Debian 10 and I'm trying to NAT masquerade it's output interface (enp0s8) so that it's clients (VMs connected to it) can access the Internet.
All interfaces in the system have an IP. I've already enabled forwarding with:
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
And then I executed:
iptables -t nat -A POSTROUTING -o enp0s8 -j MASQUERADE
However, whenever I execute the above, the following happens:
And no matter how many times I iptables --flush -t nat and repeat the process, the result is always the same. The rule I want to apply is never saved properly and the client's IPs are never masked.
What is the issue here? Almost all tutorials say this is the correct way for masquerading.
I've also tried using nftables, without success.
It is already showing the right output. To show the rules with the interface details, you need to use,
iptables -t nat -L -n -v
And btw, if you have setup NAT networking, it is already taken care to connect outside.
And have you set the default gateway of your clients to this box?

Iptables, enforce multiple rules at the same time

I am learning how to use iptables in Ubuntu
there is a server and two clients
my professor asks me to finish the three task below at once:
1.block all accesses from a client except ssh and web access
2.allow at most 2 ssh connections from each client.
3.allow at most 3 total tcp connections from each client.
I can set those rules using 3 command and i think he wants us to use a single command to finish three tasks at once.
I tried:sudo iptables -A INPUT -p tcp -m multiport ! --dports 22,80 --syn --dport 22 -m connlimit --connlimit-above 2 -m connlimit --connlimit-abve 3 -j DROP
But it didn't work
Why don't you just ask him what he wants? I don't think it is possible to do so at least based on the fact that you want to introduce both rejecting and accepting rules.
If it is really necessary to do just in one line, you can use && operator between your iptables commands as follows:
iptables your_rule1 && iptables your_rule2 && iptables your_rule3

Connect BeagleBone Black to Internet

I am trying to use this tutorial to connect to the internet from the BeagleBone Black: https://elementztechblog.wordpress.com/2014/12/22/sharing-internet-using-network-over-usb-in-beaglebone-black/
The IpTables steps do not seem to yield the correct configuration. For example:
iptables --table nat -A POSTROUTING -o wlp2s0 -j MASQUERADE
creates the following configuration:
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- localhost/16 anywhere
MASQUERADE all -- anywhere anywhere
Why do I have anywhere as destination when I clearly specify wlp2s0 ? Can anyone please help ?
iptables -t nat -L doesn't seem to show additional information like interfaces.
While it's meant to be for save/restore and machine-readable, I much prefer the output of iptables-save due to its completeness.
In your case this should show you the complete configuration for the "nat" table:
iptables-save -t nat

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

how to add new iptables rule based on current rule

I haven't really played around at all with iptables so I am quite clueless here. This MySQL server I'm currently working on rejects all connections except for whitelisted sources. I need to add a new IP but not sure how to duplicate the current rule
iptable -L lists this rule that i need to duplicate:
ACCEPT tcp -- 10.65.0.1 anywhere tcp dpt:mysql
How would I go about adding a new rule in for a different IP address?
edit: I guess I should add that I've been looking at different examples and instructions but before I try anything I just wanted to post the question here to see if anybody can provide the exact command to add the rule.
just for the record here's the answer:
iptables -A INPUT -p tcp -s $IP_ADDRESS -m tcp --dport 3306 -j ACCEPT