mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-31 16:35:23 +00:00
Merge pull request #871 from balena-io/867-block-ipv6
Apply iptables rules to ipv6
This commit is contained in:
commit
a7b709bf34
6
entry.sh
6
entry.sh
@ -46,4 +46,10 @@ if [ ! -z "${BALENA_ROOT_CA}" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Mount the host kernel module path onto the expected location
|
||||||
|
# We need to do this as busybox doesn't support using a custom location
|
||||||
|
ln -s /mnt/root/lib/modules /lib/modules
|
||||||
|
# Now load the ip6_tables kernel module, so we can do filtering on ipv6 addresses
|
||||||
|
modprobe ip6_tables
|
||||||
|
|
||||||
exec node /usr/src/app/dist/app.js
|
exec node /usr/src/app/dist/app.js
|
||||||
|
@ -1,35 +1,42 @@
|
|||||||
import * as Promise from 'bluebird';
|
import * as Bluebird from 'bluebird';
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
|
|
||||||
// The following is exported so that we stub it in the tests
|
// The following is exported so that we stub it in the tests
|
||||||
export const execAsync = Promise.promisify(childProcess.exec);
|
export const execAsync: (args: string) => Bluebird<string> = Bluebird.promisify(
|
||||||
|
childProcess.exec,
|
||||||
|
);
|
||||||
|
|
||||||
function clearIptablesRule(rule: string): Promise<void> {
|
function applyIptablesArgs(args: string): Bluebird<void> {
|
||||||
return execAsync(`iptables -D ${rule}`).return();
|
return Bluebird.all([
|
||||||
|
execAsync(`iptables ${args}`),
|
||||||
|
execAsync(`ip6tables ${args}`),
|
||||||
|
]).return();
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAndAppendIptablesRule(rule: string): Promise<void> {
|
function clearIptablesRule(rule: string): Bluebird<void> {
|
||||||
return clearIptablesRule(rule)
|
return applyIptablesArgs(`-D ${rule}`);
|
||||||
.catchReturn(null)
|
|
||||||
.then(() => execAsync(`iptables -A ${rule}`))
|
|
||||||
.return();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAndInsertIptablesRule(rule: string): Promise<void> {
|
function clearAndAppendIptablesRule(rule: string): Bluebird<void> {
|
||||||
return clearIptablesRule(rule)
|
return clearIptablesRule(rule)
|
||||||
.catchReturn(null)
|
.catchReturn(null)
|
||||||
.then(() => execAsync(`iptables -I ${rule}`))
|
.then(() => applyIptablesArgs(`-A ${rule}`));
|
||||||
.return();
|
}
|
||||||
|
|
||||||
|
function clearAndInsertIptablesRule(rule: string): Bluebird<void> {
|
||||||
|
return clearIptablesRule(rule)
|
||||||
|
.catchReturn(null)
|
||||||
|
.then(() => applyIptablesArgs(`-I ${rule}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rejectOnAllInterfacesExcept(
|
export function rejectOnAllInterfacesExcept(
|
||||||
allowedInterfaces: string[],
|
allowedInterfaces: string[],
|
||||||
port: number,
|
port: number,
|
||||||
): Promise<void> {
|
): Bluebird<void> {
|
||||||
// We delete each rule and create it again to ensure ordering (all ACCEPTs before the REJECT/DROP).
|
// 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.
|
// This is especially important after a supervisor update.
|
||||||
return (
|
return (
|
||||||
Promise.each(allowedInterfaces, iface =>
|
Bluebird.each(allowedInterfaces, iface =>
|
||||||
clearAndInsertIptablesRule(
|
clearAndInsertIptablesRule(
|
||||||
`INPUT -p tcp --dport ${port} -i ${iface} -j ACCEPT`,
|
`INPUT -p tcp --dport ${port} -i ${iface} -j ACCEPT`,
|
||||||
),
|
),
|
||||||
@ -41,11 +48,10 @@ export function rejectOnAllInterfacesExcept(
|
|||||||
.catch(() =>
|
.catch(() =>
|
||||||
clearAndAppendIptablesRule(`INPUT -p tcp --dport ${port} -j DROP`),
|
clearAndAppendIptablesRule(`INPUT -p tcp --dport ${port} -j DROP`),
|
||||||
)
|
)
|
||||||
.return()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeRejections(port: number): Promise<void> {
|
export function removeRejections(port: number): Bluebird<void> {
|
||||||
return clearIptablesRule(`INPUT -p tcp --dport ${port} -j REJECT`)
|
return clearIptablesRule(`INPUT -p tcp --dport ${port} -j REJECT`)
|
||||||
.catchReturn(null)
|
.catchReturn(null)
|
||||||
.then(() => clearIptablesRule(`INPUT -p tcp --dport ${port} -j DROP`))
|
.then(() => clearIptablesRule(`INPUT -p tcp --dport ${port} -j DROP`))
|
||||||
|
@ -10,13 +10,19 @@ describe 'iptables', ->
|
|||||||
stub(iptables, 'execAsync').returns(Promise.resolve())
|
stub(iptables, 'execAsync').returns(Promise.resolve())
|
||||||
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
||||||
.then ->
|
.then ->
|
||||||
expect(iptables.execAsync.callCount).to.equal(6)
|
expect(iptables.execAsync.callCount).to.equal(12)
|
||||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
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 -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 -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 -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 -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 -A INPUT -p tcp --dport 42 -j REJECT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||||
.then ->
|
.then ->
|
||||||
iptables.execAsync.restore()
|
iptables.execAsync.restore()
|
||||||
|
|
||||||
@ -28,7 +34,7 @@ describe 'iptables', ->
|
|||||||
Promise.resolve()
|
Promise.resolve()
|
||||||
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
iptables.rejectOnAllInterfacesExcept(['foo', 'bar'], 42)
|
||||||
.then ->
|
.then ->
|
||||||
expect(iptables.execAsync.callCount).to.equal(8)
|
expect(iptables.execAsync.callCount).to.equal(16)
|
||||||
expect(iptables.execAsync).to.be.calledWith('iptables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
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 -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 -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||||
@ -37,5 +43,13 @@ describe 'iptables', ->
|
|||||||
expect(iptables.execAsync).to.be.calledWith('iptables -A 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 -D INPUT -p tcp --dport 42 -j DROP')
|
||||||
expect(iptables.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j DROP')
|
expect(iptables.execAsync).to.be.calledWith('iptables -A INPUT -p tcp --dport 42 -j DROP')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -I INPUT -p tcp --dport 42 -i foo -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -I INPUT -p tcp --dport 42 -i bar -j ACCEPT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -j REJECT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -A INPUT -p tcp --dport 42 -j REJECT')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -D INPUT -p tcp --dport 42 -j DROP')
|
||||||
|
expect(iptables.execAsync).to.be.calledWith('ip6tables -A INPUT -p tcp --dport 42 -j DROP')
|
||||||
.then ->
|
.then ->
|
||||||
iptables.execAsync.restore()
|
iptables.execAsync.restore()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user