sed insert a line before the last string in a certain pattern - awk

I have a config file with lines:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
and I am trying to insert a line -I FORWARD -m physdev --physdev-in eth2 -j DROP between *filter and first COMMIT and only before the COMMIT in that pattern .so that resulting output looks like :
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
I have tried several ways and nearest solution I have reached is that I can append before every line in that pattern by using sed:
sed '/\*filter/,/COMMIT/i\FORWARD -m physdev --physdev-in eth2 -j DROP' file
please suggest a pattern that I can insert only before last ("COMMIT") line in that filtered pattern ?

Using awk I can write,
/^\*filter$/{found++}
found && /COMMIT/ {
print "-I FORWARD -m physdev --physdev-in eth2 -j DROP";
found=0
}
1
What is does?
/^\*filter$/{found++} If current line is *filter, increament found by one.
found && /COMMIT/ If the current line has COMMIT and filter is non zero,
Print the string that we need to print and set the found to zero.
1 This is always true, in that case awk performs the default task to print the current line.
Example
$ awk '/^\*filter$/{found++} found && /COMMIT/{print "-I FORWARD -m physdev --physdev-in eth2 -j DROP"; found=0} 1' file
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:sdfilter - [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A sdfilter -j DROP
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:ds - [0:0]
-A POSTROUTING -o dev -j MASQUERADE
COMMIT
*filter
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o dev -j MASQUERADE
-I FORWARD -m physdev --physdev-in eth2 -j DROP
COMMIT

This might work for you (GNU sed):
sed -e '/^\*filter/,/^COMMIT/{/^COMMIT/{i-I FORWARD -m physdev --physdev-in eth2 -j DROP' -e ':a;n;ba}}' file
Find the range of lines between *filter and COMMIT then insert the required string before the line containing COMMIT and finally print all following lines.

Here it comes sed answer:
sed -n -r '/COMMIT/{x; s/(\*filter.*)/\1\n-I FORWARD -m physdev --physdev-in eth2 -j DROP/; p; x;p; b end }; H; b; :end n; p; b end' config_file | sed -e '1d'
Replace --inserted text-- with text that will be appended before first 'COMMIT', plaese.
Explanation
H appends current line to buffer
b <label> - go to
: <label> - definition
b - with no simply ends current line processing
n - go to next line
x - swap pattern and hold buffer (there are only thoose two in sed)
p - print pattern buffer on screen

Related

`iiptables input policy drop` becomes `all forward drop`

iptablses drops all inputs.
Then forward that is being transferred will also be dropped.
INPUT should not affect FORWARD in my perception....
sudo iptables -t nat -A POSTROUTING -o $2 -j MASQUERADE
sudo iptables -A FORWARD -i $2 -o $1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i $1 -o $2 -j ACCEPT
sudo iptables -P INPUT DROP
This solved it.
sudo iptables -t nat -A POSTROUTING -o $2 -j MASQUERADE
sudo iptables -A FORWARD -i $2 -o $1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i $1 -o $2 -j ACCEPT
sudo iptables -t filter -A INPUT -i eth0 -j DROP

iptables - Two entries for one rule | iptables -A INPUT -s localhost -j ACCEPT

I am issuing the following rule from the shell prompt:
iptables -A INPUT -s localhost -j ACCEPT
After that, when I check iptables -L, I see two entries for the same.
The summary of iptables-save -c before and after:
root#debian:~# iptables-save -c
# Generated by iptables-save v1.4.21 on Fri Nov 3 09:11:15 2017
*filter
:INPUT ACCEPT [8:528]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5:492]
COMMIT
# Completed on Fri Nov 3 09:11:15 2017
root#debian:~# iptables -A INPUT -s localhost -j ACCEPT
root#debian:~# iptables-save -c
# Generated by iptables-save v1.4.21 on Fri Nov 3 09:11:24 2017
*filter
:INPUT ACCEPT [6:396]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [4:496]
[0:0] -A INPUT -s 127.0.0.1/32 -j ACCEPT
[0:0] -A INPUT -s 127.0.0.1/32 -j ACCEPT
COMMIT
# Completed on Fri Nov 3 09:11:24 2017
root#debian:~#
Any idea, why there are two entries for one rule?

sed delete patterned lines but ignore commented lines with the same pattern

I have lines in my config file :
#-A FORWARD -i eth2 -j ACCEPT
#-A FORWARD -m physdev --physdev-in eth0 -j DROP
#-A FORWARD -m physdev --physdev-in eth2 -j DROP
-A FORWARD -m physdev --physdev-in eth0 -j DROP
-A FORWARD -m physdev --physdev-in eth2 -j DROP
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
Lines that are having 'physdev' string are of my interest and want to apply a (sed)rule on this file such that rule has to ignore comment lines having 'physdev' string and delete the uncommented lines having 'physdev' string. Could you please suggest an sed delete pattern or any awk pattern.
Given:
$ cat file
#-A FORWARD -i eth2 -j ACCEPT
#-A FORWARD -m physdev --physdev-in eth0 -j DROP
#-A FORWARD -m physdev --physdev-in eth2 -j DROP
-A FORWARD -m physdev --physdev-in eth0 -j DROP
-A FORWARD -m physdev --physdev-in eth2 -j DROP
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
You can do:
$ awk '$1~/^#/{print; next} /physdev/{next} 1' file
#-A FORWARD -i eth2 -j ACCEPT
#-A FORWARD -m physdev --physdev-in eth0 -j DROP
#-A FORWARD -m physdev --physdev-in eth2 -j DROP
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
So, if you want to delete all uncommented lines containig physdev (that's what you want, right?), sed is at least as elegant as awk:
sed -e '/^[^#].*physdev/d' file
If you want the changes to be written in the file, use sed -i -e ...
sed -e '/^#/n;/physdev/d' file
/^#/n just advances to the next line of the input whever a line begins with #
This has the effect of ignoring ALL subsequent sed commands when /^#/ matches. So if you know you always want to retain all lines beginning with #, making /^#/n the first command will do so, regardless of how many or how complex the subsequent commands get.

Iptable rules not behaving as expected

I have the following iptable rules for a new system.
Basically I am trying to allow incoming www, ssl and ssh and allow outgoing ftp,ssh,smtp,dns,www and ssl connections. Plus a special rules for an outgoing mysql connection to a specific mysql server, a DoS attack helper and some dropped packet logging. All other connections I want dropped.
My trouble is, every single time I run the shell script for these rules, I get locked out tighter than a drum. It drops the established ssh session and won't allow me to begin a new one. I have to reboot through a console as even flushing the rules in a console session does not help.
It does not matter if the fallback rules (top three after the flush) are at the beginning or the end. I've tried many ways and I am hoping a new set of eyes may see what I am missing:
iptables -F
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 80,443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --dport 21,22,25,53,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m multiport --sport 21,22,25,53,80,443 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -p tcp -s 172.xxx.xxx.xxx --sport 1024:65535 -d 172.xxx.xxx.xxx --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -s 172.xxx.xxx.xxx --sport 3306 -d 172.xxx.xxx.xxx --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 80,443 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
iptables -N LOGGING
iptables -A INPUT -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7
iptables -A LOGGING -j DROP
Any help would be appreciated. NOTE: I obfuscated the internal IP for posting.

keepalived works well without iptables

I have setup keepalived, and it works well only when I stop the iptables service. My iptables config like this, Please tell me what rules should added for keepalived
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5666 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Just slove this problem these days,Haha
Do:
iptables -I INPUT -d 224.0.0.0/8 -j ACCEPT
iptables -I INPUT -p vrrp -j ACCEPT
You must accept ip protocol 112 (vrrp) and multicast traffic to 224.0.0.18. If you are using auth_type AH then you must accept proto 51
iptables -I INPUT -p 112 -d 224.0.0.18 -j ACCEPT
iptables -I INPUT -p 51 -d 224.0.0.18 -j ACCEPT
to MASTER keepalived machine:
iptables -I OUTPUT -p vrrp -s 192.168.10.1 -d 224.0.0.0/24 -j ACCEPT
to BACKUP keepalived machine:
iptables -I INPUT -p vrrp -s 192.168.10.1 -d 224.0.0.0/24 -j ACCEPT
192.168.10.1 is the master keepalived ip