mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-18 18:56:24 +00:00
Convert iptables module to typescript
Change-type: patch Signed-off-by: Cameron Diver <cameron@resin.io>
This commit is contained in:
parent
352a5684b3
commit
5622ddce94
@ -1,25 +0,0 @@
|
||||
Promise = require 'bluebird'
|
||||
childProcess = Promise.promisifyAll(require('child_process'))
|
||||
|
||||
clearAndAppendIptablesRule = (rule) ->
|
||||
childProcess.execAsync("iptables -D #{rule}")
|
||||
.catchReturn()
|
||||
.then ->
|
||||
childProcess.execAsync("iptables -A #{rule}")
|
||||
|
||||
clearAndInsertIptablesRule = (rule) ->
|
||||
childProcess.execAsync("iptables -D #{rule}")
|
||||
.catchReturn()
|
||||
.then ->
|
||||
childProcess.execAsync("iptables -I #{rule}")
|
||||
|
||||
exports.rejectOnAllInterfacesExcept = (allowedInterfaces, port) ->
|
||||
# We delete each rule and create it again to ensure ordering (all ACCEPTs before the REJECT/DROP).
|
||||
# This is especially important after a supervisor update.
|
||||
Promise.each allowedInterfaces, (iface) ->
|
||||
clearAndInsertIptablesRule("INPUT -p tcp --dport #{port} -i #{iface} -j ACCEPT")
|
||||
.then ->
|
||||
clearAndAppendIptablesRule("INPUT -p tcp --dport #{port} -j REJECT")
|
||||
.catch ->
|
||||
# On systems without REJECT support, fall back to DROP
|
||||
clearAndAppendIptablesRule("INPUT -p tcp --dport #{port} -j DROP")
|
32
src/lib/iptables.ts
Normal file
32
src/lib/iptables.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import * as Promise from 'bluebird';
|
||||
import * as childProcess from 'child_process';
|
||||
|
||||
// The following is exported so that we stub it in the tests
|
||||
export const execAsync = Promise.promisify(childProcess.exec);
|
||||
|
||||
function clearAndAppendIptablesRule(rule: string): Promise<void> {
|
||||
return execAsync(`iptables -D ${rule}`)
|
||||
.catchReturn(null)
|
||||
.then(() => execAsync(`iptables -A ${rule}`))
|
||||
.return();
|
||||
}
|
||||
|
||||
function clearAndInsertIptablesRule(rule: string): Promise<void> {
|
||||
return execAsync(`iptables -D ${rule}`)
|
||||
.catchReturn(null)
|
||||
.then(() => execAsync(`iptables -I ${rule}`))
|
||||
.return();
|
||||
}
|
||||
|
||||
export function rejectOnAllInterfacesExcept(
|
||||
allowedInterfaces: string[],
|
||||
port: number,
|
||||
): Promise<void> {
|
||||
// We delete each rule and create it again to ensure ordering (all ACCEPTs before the REJECT/DROP).
|
||||
// This is especially important after a supervisor update.
|
||||
return Promise.each(allowedInterfaces, (iface) => clearAndInsertIptablesRule(`INPUT -p tcp --dport ${port} -i ${iface} -j ACCEPT`))
|
||||
.then(() => clearAndAppendIptablesRule(`INPUT -p tcp --dport ${port} -j REJECT`))
|
||||
// On systems without REJECT support, fall back to DROP
|
||||
.catch(() => clearAndAppendIptablesRule(`INPUT -p tcp --dport ${port} -j DROP`))
|
||||
.return();
|
||||
}
|
@ -1,43 +1,41 @@
|
||||
Promise = require 'bluebird'
|
||||
iptables = require '../src/lib/iptables'
|
||||
|
||||
childProcess = require('child_process')
|
||||
|
||||
m = require 'mochainon'
|
||||
{ stub } = m.sinon
|
||||
{ expect } = m.chai
|
||||
|
||||
describe 'iptables', ->
|
||||
it 'calls iptables to delete and recreate rules to block a port', ->
|
||||
stub(childProcess, 'execAsync').returns(Promise.resolve())
|
||||
stub(iptables, 'execAsync').returns(Promise.resolve())
|
||||
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
||||
.then ->
|
||||
expect(childProcess.execAsync.callCount).to.equal(6)
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(iptables.execAsync.callCount).to.equal(6)
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||
.then ->
|
||||
childProcess.execAsync.restore()
|
||||
iptables.execAsync.restore()
|
||||
|
||||
it "falls back to blocking the port with DROP if there's no REJECT support", ->
|
||||
stub(childProcess, 'execAsync').callsFake (cmd) ->
|
||||
stub(iptables, 'execAsync').callsFake (cmd) ->
|
||||
if /REJECT$/.test(cmd)
|
||||
Promise.reject()
|
||||
else
|
||||
Promise.resolve()
|
||||
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
||||
.then ->
|
||||
expect(childProcess.execAsync.callCount).to.equal(8)
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j DROP')
|
||||
expect(childProcess.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j DROP')
|
||||
expect(iptables.execAsync.callCount).to.equal(8)
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -j DROP')
|
||||
expect(iptables.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j DROP')
|
||||
.then ->
|
||||
childProcess.execAsync.restore()
|
||||
iptables.execAsync.restore()
|
||||
|
Loading…
Reference in New Issue
Block a user