0

I am doing a script that add a sample of /etc/iptables.rules file on my server.

/etc/iptables.rules

*filter

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
${DROP_INTERFACE}
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT

COMMIT

Then, the node JS script add after ${DROP_INTERFACE} multiple lines then remove the tag :

app.js

// retrieve public interface in order to restrict access
var names = _.pluck(results.publicIfaceList, 'name');
var dropInterface = []; // eg : ['eth1', 'eth2"]
for(var i = 0; i < names.length; i++){
    // add a new DROP rule
    dropInterface.push("-A FORWARD -i "+names[i]+" -j DROP");
}

// for each rules
async.eachSeries(dropInterface, function iterator(item, next){
    // add a line after ${DROP_INTERFACE}
    var cmd = "sed -i '/${DROP_INTERFACE}/a " + item + "' " + FirewallConstants.IPTABLES_RULES;
    bash.execute(cmd, function(output){
        next();
    }); 
}, function done(){
    // remove the line with ${DROP_INTERFACE}
    var cmd = "sed -i '/${DROP_INTERFACE}/d' " + FirewallConstants.IPTABLES_RULES;
    bash.execute(cmd, function(output){
        cb();
    });
}); 

I have also tried to replace the tag with multiple lines at once :

var names = _.pluck(results.publicIfaceList, 'name');
var dropInterface = [];
for(var i = 0; i < names.length; i++){
    dropInterface.push("-A FORWARD -i "+names[i]+" -j DROP");
}
var cmd = "sed -i '/${DROP_INTERFACE}/c\\"+dropInterface.join('\n')+"' /etc/iptables.rules";
bash.execute(cmd, function (output){
    cb();
});

None of my methods worked, I had different errors like :

  1. Doesn't replace the string at all
  2. Tested with !DROP_INTERFACE instead of ${DROP_INTERFACE}, only the "!" character was removed.
  3. ${DROP_INTERFACE} is a wrong occurrence (or something similar).

Does anyone has a working example of a multiple lines text insertion using sed from a nodejs script ?

The main goal is to drop access from this interface to any services listening on public interfaces (0.0.0.0).

Dimitri Kopriwa
  • 13,139
  • 27
  • 98
  • 204

1 Answers1

1

Worked for me :

        var names = _.pluck(results.publicIfaceList, 'name');
        var dropInterface = [];
        for(var i = 0; i < names.length; i++){
            dropInterface.push("-A FORWARD -i "+names[i]+" -j DROP");
        }

        fs.readFile(FirewallConstants.IPTABLES_RULES, 'utf8', function (err,data) {
            if (err) {
                cb(err);
                return;
            }

            var result = data.replace("${DROP_INTERFACE}", dropInterface.join('\n'));
            fs.writeFile(FirewallConstants.IPTABLES_RULES, result, 'utf8', function (err) {
                cb(err);
            });
        });
Dimitri Kopriwa
  • 13,139
  • 27
  • 98
  • 204