From acb20cfa700114b86b25d58900a075897da1ec08 Mon Sep 17 00:00:00 2001 From: Matthew Sykes Date: Wed, 9 Jul 2014 14:24:00 -0700 Subject: [PATCH] Enable opt-in network access to inherited DNS servers Warden containers inherit the DNS servers from the host DEA's /etc/resolv.conf. With the addition of app security groups and a global deny policy, DNS is no longer accessible by default from containers; that made bosh-lite users very sad... When dea_next.allow_inherited_dns is true, rules are added to the default warden chain to allow access to the inherited DNS servers. [#71585346] Signed-off-by: Zach Robinson --- warden/lib/warden/config.rb | 16 +++++++++------- warden/lib/warden/container/features/net.rb | 3 +++ warden/lib/warden/container/linux.rb | 1 + warden/root/linux/net.sh | 7 +++++++ warden/spec/container/linux_spec.rb | 16 ++++++++++++++++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/warden/lib/warden/config.rb b/warden/lib/warden/config.rb index 3e3664d1..3648108b 100644 --- a/warden/lib/warden/config.rb +++ b/warden/lib/warden/config.rb @@ -92,6 +92,7 @@ def self.network_defaults "deny_networks" => [], "allow_networks" => [], "mtu" => 1500, + "allow_inherited_dns" => false, } end @@ -102,13 +103,14 @@ def self.network_schema optional("pool_network") => String, # Present for Backwards compatibility - optional("pool_start_address") => String, - optional("pool_size") => Integer, - optional("release_delay") => Integer, - optional("mtu") => Integer, - - "deny_networks" => [String], - "allow_networks" => [String], + optional("pool_start_address") => String, + optional("pool_size") => Integer, + optional("release_delay") => Integer, + optional("mtu") => Integer, + optional("allow_inherited_dns") => bool, + + "deny_networks" => [String], + "allow_networks" => [String], } end end diff --git a/warden/lib/warden/container/features/net.rb b/warden/lib/warden/container/features/net.rb index 058d5324..79428177 100644 --- a/warden/lib/warden/container/features/net.rb +++ b/warden/lib/warden/container/features/net.rb @@ -191,11 +191,14 @@ module ClassMethods # Network whitelist attr_accessor :allow_networks + attr_accessor :allow_inherited_dns + def setup(config) super(config) self.deny_networks = config.network["deny_networks"] self.allow_networks = config.network["allow_networks"] + self.allow_inherited_dns = config.network["allow_inherited_dns"] end end diff --git a/warden/lib/warden/container/linux.rb b/warden/lib/warden/container/linux.rb index 16f938c0..c39f7cda 100644 --- a/warden/lib/warden/container/linux.rb +++ b/warden/lib/warden/container/linux.rb @@ -48,6 +48,7 @@ def setup(config) "CONTAINER_DEPOT_PATH" => container_depot_path, "CONTAINER_DEPOT_MOUNT_POINT_PATH" => container_depot_mount_point_path, "DISK_QUOTA_ENABLED" => disk_quota_enabled.to_s, + "ALLOW_INHERITED_DNS" => allow_inherited_dns.to_s, }, } diff --git a/warden/root/linux/net.sh b/warden/root/linux/net.sh index 280bf919..7a9d6b46 100755 --- a/warden/root/linux/net.sh +++ b/warden/root/linux/net.sh @@ -115,6 +115,13 @@ function setup_filter() { iptables -A ${filter_default_chain} --destination "$n" --jump DROP done + if [ "$ALLOW_INHERITED_DNS" = "true" ]; then + for ns in `grep nameserver /etc/resolv.conf | cut -f2- -d' '`; do + iptables -A ${filter_default_chain} -d ${ns} -p udp -m udp --dport 53 --jump ACCEPT -m comment --comment 'allow-inherited-dns' + iptables -A ${filter_default_chain} -d ${ns} -p tcp -m tcp --dport 53 --jump ACCEPT -m comment --comment 'allow-inherited-dns' + done + fi + iptables -A ${filter_default_chain} --jump REJECT # Accept packets related to previously established connections diff --git a/warden/spec/container/linux_spec.rb b/warden/spec/container/linux_spec.rb index 9c4b934a..d0b4bf86 100644 --- a/warden/spec/container/linux_spec.rb +++ b/warden/spec/container/linux_spec.rb @@ -24,6 +24,7 @@ let(:netmask) { Warden::Network::Netmask.new(255, 255, 255, 252) } let(:allow_networks) { [] } let(:deny_networks) { [] } + let(:allow_inherited_dns) { false } let(:mtu) { 1500 } let(:job_output_limit) { 100 * 1024 } let(:server_pidfile) { nil } @@ -116,6 +117,7 @@ def start_warden "pool_start_address" => @start_address, "pool_size" => 64, "mtu" => mtu, + "allow_inherited_dns" => allow_inherited_dns, "allow_networks" => allow_networks, "deny_networks" => deny_networks}, "port" => { @@ -619,6 +621,20 @@ def host_first_ipv4 end end + context "when allow_inherited_dns is true" do + let(:allow_inherited_dns) { true } + + it "allows traffic to the dns server" do + client_script = <<-EOF + for ns in `grep nameserver /etc/resolv.conf | cut -f2- -d' '`; do + dig @${ns} +time=1 +tries=1 example.com > /dev/null || exit 1 + done + EOF + response = run(@containers[0][:handle], client_script) + expect(response.exit_status).to eq 0 + end + end + context "when allow_networks is configured" do # Allow traffic to the first two subnets let(:allow_networks) do