All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit f1206314 authored by Mike Hibler's avatar Mike Hibler

More tightly connect the notion of a firewall and the security level.

If you specify an explicit firewall, you are implicitly assigned security
level 2 and you cannot explicitly specify the security level.  Likewise,
if you specify a security level, you cannot also specify a firewall.

The reason for this is that security level 1 (aka "Blue") now has a slightly
different meaning.  It is intended for protecting the inside from the outside
rather than visa-versa.  The only practical implication of this is that for
level 1, we don't do all the fancy power-off-boot-into-MFS-zapbootblock stuff
that we do for higher levels.

Anyway, I wanted to make sure that if you specify your own firewall, you
DO have to go through the full cleansing swapout since we can't trust a
firewall that the Average Joe sets up.
parent 6090e114
......@@ -210,8 +210,8 @@ use vars qw(@ISA @EXPORT);
TBGetUniqueIndex
TBExptMinMaxNodes TBExptSecurityLevel TBExptIDX
TBDB_SECLEVEL_GREEN TBDB_SECLEVEL_YELLOW
TBDB_SECLEVEL_ORANGE TBDB_SECLEVEL_RED
TBDB_SECLEVEL_GREEN TBDB_SECLEVEL_BLUE TBDB_SECLEVEL_YELLOW
TBDB_SECLEVEL_ORANGE TBDB_SECLEVEL_RED TBDB_SECLEVEL_ZAPDISK
TBExptSetPanicBit TBExptGetPanicBit TBExptClearPanicBit
......@@ -657,9 +657,13 @@ sub TBDB_CHECKDBSLOT_ERROR() { 0x2; }
# Security Levels.
sub TBDB_SECLEVEL_GREEN() { 0; }
sub TBDB_SECLEVEL_YELLOW() { 1; }
sub TBDB_SECLEVEL_ORANGE() { 2; }
sub TBDB_SECLEVEL_RED() { 3; }
sub TBDB_SECLEVEL_BLUE() { 1; }
sub TBDB_SECLEVEL_YELLOW() { 2; }
sub TBDB_SECLEVEL_ORANGE() { 3; }
sub TBDB_SECLEVEL_RED() { 4; }
# This is the level at which we get extremely cautious when swapping out
sub TBDB_SECLEVEL_ZAPDISK() { TBDB_SECLEVEL_YELLOW; }
#
# A hash of all tables that contain information about physical nodes - the
......
......@@ -19,6 +19,8 @@ namespace eval GLOBALS {
Firewall instproc init {s} {
global ::GLOBALS::last_class
var_import ::GLOBALS::explicit_firewall
var_import ::GLOBALS::security_level
$self set sim $s
......@@ -36,6 +38,13 @@ Firewall instproc init {s} {
if {[$s add_firewall $self] == 0} {
set ::GLOBALS::last_class $self
}
if {$security_level} {
perror "\[add_firewall] cannot combine firewall with security-level"
}
# avoid conflicts with security_level
set explicit_firewall 1
}
Firewall instproc rename {old new} {
......
......@@ -2,9 +2,17 @@
# This file is intended to be included into another NS file. It is not
# a stand alone file.
#
if {${::GLOBALS::security_level} >= 1} {
if {${::GLOBALS::explicit_firewall}} {
# explicit firewalls require disk zappage
set ::GLOBALS::security_level ${::GLOBALS::security_level_diskzap}
} elseif {${::GLOBALS::security_level} >= 1} {
# Set up a firewall
# XXX hack: have to clear the security level temporarily
set sl ${::GLOBALS::security_level}
set ::GLOBALS::security_level 0
set fw [new Firewall $ns]
set ::GLOBALS::security_level $sl
$fw set-type ipfw2-vlan
if {${::GLOBALS::security_level} == 1} {
......
......@@ -263,8 +263,13 @@ namespace eval GLOBALS {
variable elabinelab_eid {}
variable elabinelab_cvstag {}
# Security level. Defaults to green
# Security level. Defaults to 0 ("green")
# If explicit_firewall is set, then you cannot also give a security level.
# security_level_diskzap is the level at which we need to zap the disk
# at swapout time. This value (2) is encoded in libdb.pm also.
variable security_level 0
variable explicit_firewall 0
variable security_level_diskzap 2
# List of source files.
variable sourcefile_list {}
......
......@@ -368,6 +368,7 @@ Simulator instproc run {} {
var_import ::GLOBALS::elabinelab_eid
var_import ::GLOBALS::elabinelab_cvstag
var_import ::GLOBALS::security_level
var_import ::GLOBALS::explicit_firewall
var_import ::GLOBALS::sourcefile_list
if {$ran == 1} {
......@@ -383,7 +384,7 @@ Simulator instproc run {} {
}
uplevel 1 real_source "@prefix@/lib/ns2ir/${nsfilename}"
}
if {$security_level} {
if {$security_level || $explicit_firewall} {
uplevel 1 real_source "@prefix@/lib/ns2ir/fw.ns"
}
......
......@@ -1492,6 +1492,11 @@ proc tb-set-node-inner-elab-role {node role} {
#
proc tb-set-security-level {level} {
var_import ::GLOBALS::security_level
var_import ::GLOBALS::explicit_firewall
if {$explicit_firewall} {
perror "\[tb-set-security-level] cannot combine with explicit firewall"
}
switch -- $level {
"Green" {
......
......@@ -1081,7 +1081,7 @@ sub doSwapin($) {
#
if ($firewalled) {
tberror "Not retrying, ".
"firewall may be preventing setup.";
"possibly an error in firewall setup or configuration.";
return 1;
}
......@@ -1442,9 +1442,10 @@ sub doFW($$$$) {
#
sub undoFWNodes($$;@) {
my ($pid, $eid, @nodes) = @_;
my $doall = 0;
my $fwerr = 0;
my @fwstate = ();
my $doall = 0;
my $fwerr = 0;
my @fwstate = ();
my $zap = 1;
if (!defined(@nodes) || @nodes == 0) {
@nodes = ExpNodes($pid, $eid, 1);
......@@ -1471,35 +1472,53 @@ sub undoFWNodes($$;@) {
}
#
# First turn off all the machines.
# If we fail, the firewall in left in place, and some nodes may
# be powered off.
# At the lowest level of security, we don't do the diskzap dance
# unless we have paniced.
#
# This level ("blue") is used for experiments where we are trying to
# protect the inside from outside; i.e., there is no bad stuff inside
# to clean up.
#
print STDERR "Powering down firewalled nodes.\n";
TBDebugTimeStamp("Powering down nodes");
system("power off @nodes");
if ($?) {
$fwerr = "Failed to power off all nodes!";
@fwstate = ("Firewall is still in place",
"Some nodes may NOT be powered off",
"Nodes NOT switched to admin MFS");
goto done;
my $paniced;
my $security_level;
if (TBExptGetPanicBit($pid, $eid, \$paniced) && $paniced == 0 &&
TBExptSecurityLevel($pid, $eid, \$security_level) &&
$security_level < TBDB_SECLEVEL_ZAPDISK()) {
$zap = 0;
}
#
# Force all nodes into admin mode.
# If we fail, the firewall is left in place.
# First turn off all the machines.
# If we fail, the firewall in left in place, and some nodes may
# be powered off.
#
my %myargs;
$myargs{'name'} = "tbswap";
$myargs{'on'} = 1;
$myargs{'clearall'} = 1;
if (TBAdminMfsSelect(\%myargs, undef, @nodes)) {
$fwerr = "Failed to force all nodes into admin mode!";
@fwstate = ("Firewall is still in place",
"All nodes are powered off",
"Not all nodes have been switched to admin MFS");
goto done;
if ($zap) {
print STDERR "Powering down firewalled nodes.\n";
TBDebugTimeStamp("Powering down nodes");
system("power off @nodes");
if ($?) {
$fwerr = "Failed to power off all nodes!";
@fwstate = ("Firewall is still in place",
"Some nodes may NOT be powered off",
"Nodes NOT switched to admin MFS");
goto done;
}
#
# Force all nodes into admin mode.
# If we fail, the firewall is left in place.
#
my %myargs;
$myargs{'name'} = "tbswap";
$myargs{'on'} = 1;
$myargs{'clearall'} = 1;
if (TBAdminMfsSelect(\%myargs, undef, @nodes)) {
$fwerr = "Failed to force all nodes into admin mode!";
@fwstate = ("Firewall is still in place",
"All nodes are powered off",
"Not all nodes have been switched to admin MFS");
goto done;
}
}
#
......@@ -1515,8 +1534,8 @@ sub undoFWNodes($$;@) {
if (doFW($pid, $eid, FWTEARDOWN, undef)) {
$fwerr = "Failed to tear down firewall!";
@fwstate = ("Firewall may NOT be in place",
"All nodes are powered off",
"All nodes set to admin mode",
$zap ? ("All nodes are powered off",
"All nodes set to admin mode") : (),
"Switch/DB firewall state could be inconsistent!");
goto done;
}
......@@ -1525,8 +1544,8 @@ sub undoFWNodes($$;@) {
if (doFW($pid, $eid, FWDELNODES, \@deleted)) {
$fwerr = "Failed to remove nodes from firewall VLAN!";
@fwstate = ("Nodes may still be in firewall VLAN",
"All nodes are powered off",
"All nodes set to admin mode");
$zap ? ("All nodes are powered off",
"All nodes set to admin mode") : ());
goto done;
}
}
......@@ -1542,25 +1561,28 @@ sub undoFWNodes($$;@) {
# let the experiment swapout finish, freeing up the nodes that
# did succeed.
#
print STDERR "Booting nodes into admin MFS and zapping bootblocks.\n";
TBDebugTimeStamp("Booting admin MFS/zapping bootblocks");
my @failed = ();
%myargs = ();
$myargs{'name'} = "tbswap";
$myargs{'command'} = "sudo /usr/local/bin/diskzap";
$myargs{'poweron'} = 1;
if (TBAdminMfsRunCmd(\%myargs, \@failed, @nodes)) {
$fwerr = "Failed to invalidate bootblocks on @failed!";
@fwstate = ("Firewall is NOT in place",
"All nodes set to admin mode");
system("power off @nodes");
if ($?) {
push(@fwstate, "Some nodes may NOT be powered off");
} else {
push(@fwstate, "All nodes are powered off");
if ($zap) {
print STDERR "Booting nodes into admin MFS and zapping bootblocks.\n";
TBDebugTimeStamp("Booting admin MFS/zapping bootblocks");
my @failed = ();
%myargs = ();
$myargs{'name'} = "tbswap";
$myargs{'command'} = "sudo /usr/local/bin/diskzap";
$myargs{'poweron'} = 1;
if (TBAdminMfsRunCmd(\%myargs, \@failed, @nodes)) {
$fwerr = "Failed to invalidate bootblocks on @failed!";
@fwstate = ("Firewall is NOT in place",
"All nodes set to admin mode");
system("power off @nodes");
if ($?) {
push(@fwstate, "Some nodes may NOT be powered off");
} else {
push(@fwstate, "All nodes are powered off");
}
push(@fwstate, "MAKE SURE THESE NODES DO NOT BOOT FROM DISK!");
}
push(@fwstate, "MAKE SURE THESE NODES DO NOT BOOT FROM DISK!");
}
done:
#
# If we had a failure when tearing down the firewall completely,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment