From 4396c48ec61c1cd807c50f64c930baaa626baf40 Mon Sep 17 00:00:00 2001 From: Evan Shi <14984764+evanyeyeye@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:48:05 -0400 Subject: [PATCH 1/3] Implement docker outgoing firewall --- restful_tango/tangoREST.py | 3 +++ tangoObjects.py | 2 ++ vmms/localDocker.py | 14 +++++++++++--- worker.py | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/restful_tango/tangoREST.py b/restful_tango/tangoREST.py index 52296771..6df59fad 100644 --- a/restful_tango/tangoREST.py +++ b/restful_tango/tangoREST.py @@ -169,6 +169,8 @@ def convertJobObj(self, dirName, jobObj): if "disable_network" in jobObj and isinstance(jobObj["disable_network"], bool): disableNetwork = jobObj["disable_network"] + allowedOutgoingIPs = jobObj["allowed_outgoing_ips"] + job = TangoJob( name=name, vm=vm, @@ -180,6 +182,7 @@ def convertJobObj(self, dirName, jobObj): accessKey=accessKey, accessKeyId=accessKeyId, disableNetwork=disableNetwork, + allowedOutgoingIPs=allowedOutgoingIPs, ) self.log.debug("inputFiles: %s" % [file.localFile for file in input]) diff --git a/tangoObjects.py b/tangoObjects.py index ed62aec1..5c2ff583 100644 --- a/tangoObjects.py +++ b/tangoObjects.py @@ -94,6 +94,7 @@ def __init__( accessKeyId=None, accessKey=None, disableNetwork=None, + allowedOutgoingIPs=None, ): self.assigned = False self.retries = 0 @@ -114,6 +115,7 @@ def __init__( self.accessKeyId = accessKeyId self.accessKey = accessKey self.disableNetwork = disableNetwork + self.allowedOutgoingIPs = (allowedOutgoingIPs,) def makeAssigned(self): self.syncRemote() diff --git a/vmms/localDocker.py b/vmms/localDocker.py index 45dda03d..d6c995a2 100644 --- a/vmms/localDocker.py +++ b/vmms/localDocker.py @@ -142,7 +142,9 @@ def copyIn(self, vm, inputFiles): ) return 0 - def runJob(self, vm, runTimeout, maxOutputFileSize, disableNetwork): + def runJob( + self, vm, runTimeout, maxOutputFileSize, disableNetwork, allowedOutgoingIPs + ): """runJob - Run a docker container by doing the follows: - mount directory corresponding to this job to /home/autolab in the container @@ -176,10 +178,16 @@ def runJob(self, vm, runTimeout, maxOutputFileSize, disableNetwork): ) ) + iptablesCmd = "" + if not disableNetwork and allowedOutgoingIPs: + for IP in allowedOutgoingIPs: + iptablesCmd += f"iptables -A OUTPUT -d {IP} -j ACCEPT; " + iptablesCmd += "iptables -A OUTPUT -j DROP;" + args = args + [ - 'cp -r mount/* autolab/; su autolab -c "%s"; \ + '%s cp -r mount/* autolab/; su autolab -c "%s"; \ cp output/feedback mount/feedback' - % autodriverCmd + % (iptablesCmd, autodriverCmd) ] self.log.debug("Running job: %s" % str(args)) diff --git a/worker.py b/worker.py index 0b37261f..e5a23d0b 100644 --- a/worker.py +++ b/worker.py @@ -292,6 +292,7 @@ def run(self): self.job.timeout, self.job.maxOutputFileSize, self.job.disableNetwork, + self.job.allowedOutgoingIPs, ) if ret["runjob"] != 0: Config.runjob_errors += 1 From 553bd1dae3e5776043a093e86802a0dd84231fca Mon Sep 17 00:00:00 2001 From: Evan Shi <14984764+evanyeyeye@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:11:56 -0400 Subject: [PATCH 2/3] Add Google DNS and request verification --- restful_tango/tangoREST.py | 6 +++++- tangoObjects.py | 2 +- vmms/localDocker.py | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/restful_tango/tangoREST.py b/restful_tango/tangoREST.py index 6df59fad..cfbe47dc 100644 --- a/restful_tango/tangoREST.py +++ b/restful_tango/tangoREST.py @@ -169,7 +169,11 @@ def convertJobObj(self, dirName, jobObj): if "disable_network" in jobObj and isinstance(jobObj["disable_network"], bool): disableNetwork = jobObj["disable_network"] - allowedOutgoingIPs = jobObj["allowed_outgoing_ips"] + allowedOutgoingIPs = None + if "allowed_outgoing_ips" in jobObj and isinstance( + jobObj["allowed_outgoing_ips"], list + ): + allowedOutgoingIPs = jobObj["allowed_outgoing_ips"] job = TangoJob( name=name, diff --git a/tangoObjects.py b/tangoObjects.py index 5c2ff583..c2a30c70 100644 --- a/tangoObjects.py +++ b/tangoObjects.py @@ -115,7 +115,7 @@ def __init__( self.accessKeyId = accessKeyId self.accessKey = accessKey self.disableNetwork = disableNetwork - self.allowedOutgoingIPs = (allowedOutgoingIPs,) + self.allowedOutgoingIPs = allowedOutgoingIPs def makeAssigned(self): self.syncRemote() diff --git a/vmms/localDocker.py b/vmms/localDocker.py index d6c995a2..e0cefdd4 100644 --- a/vmms/localDocker.py +++ b/vmms/localDocker.py @@ -165,6 +165,8 @@ def runJob( args = args + ["-m", f"{vm.memory}m"] if disableNetwork: args = args + ["--network", "none"] + if not disableNetwork and allowedOutgoingIPs: + args = args + ["--dns", "8.8.8.8", "--cap-add=NET_ADMIN"] args = args + [vm.image] args = args + ["sh", "-c"] @@ -180,6 +182,7 @@ def runJob( iptablesCmd = "" if not disableNetwork and allowedOutgoingIPs: + iptablesCmd += f"iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT; " for IP in allowedOutgoingIPs: iptablesCmd += f"iptables -A OUTPUT -d {IP} -j ACCEPT; " iptablesCmd += "iptables -A OUTPUT -j DROP;" From 70bb3a06c6359d986e260b0cdd24a1890e9849c1 Mon Sep 17 00:00:00 2001 From: Evan Shi <14984764+evanyeyeye@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:30:37 -0400 Subject: [PATCH 3/3] Fix coderabbit suggestions --- vmms/localDocker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmms/localDocker.py b/vmms/localDocker.py index e0cefdd4..02decfe4 100644 --- a/vmms/localDocker.py +++ b/vmms/localDocker.py @@ -182,7 +182,7 @@ def runJob( iptablesCmd = "" if not disableNetwork and allowedOutgoingIPs: - iptablesCmd += f"iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT; " + iptablesCmd += "iptables -A OUTPUT -d 8.8.8.8 -j ACCEPT; " for IP in allowedOutgoingIPs: iptablesCmd += f"iptables -A OUTPUT -d {IP} -j ACCEPT; " iptablesCmd += "iptables -A OUTPUT -j DROP;"