Skip to content

Commit

Permalink
feat: add dnsSupportLevel option for systems with broken DNS (fixes #397
Browse files Browse the repository at this point in the history
)
  • Loading branch information
speed47 committed Mar 20, 2024
1 parent d8f9423 commit 7423f6a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 21 deletions.
14 changes: 14 additions & 0 deletions doc/sphinx/administration/configuration/bastion_conf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Global network policies options

Those options can set a few global network policies to be applied bastion-wide.

- `dnsSupportLevel`_
- `allowedNetworks`_
- `forbiddenNetworks`_
- `ingressToEgressRules`_
Expand Down Expand Up @@ -345,6 +346,19 @@ Additional parameters that will be passed as-is to mosh-server. See ``man mosh-s
Global network policies
-----------------------

.. _dnsSupportLevel:

dnsSupportLevel
***************

:Type: ``integer between 0 and 2``

:Default: ``2``

If set to 0, The Bastion will never attempt to do DNS or reverse-DNS resolutions, and return an error if you request connection to a hostname instead of an IP. Use this if you know there's no working DNS in your environment and only use IPs everywhere.
If set to 1, The Bastion will not attempt to do DNS or reverse-DNS resolutions unless you force it to (i.e. by requesting connection to a hostname instead of an IP). You may use this if for example you have well-known hostnames in /etc/hosts, but don't have a working DNS (which would imply that reverse-DNS resolutions will always fail).
If set to 2, The Bastion will make the assumption that you have a working DNS setup, and will do DNS and reverse-DNS resolutions normally.

.. _allowedNetworks:

allowedNetworks
Expand Down
7 changes: 7 additions & 0 deletions etc/bastion/bastion.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@
# > Global network policies
# >> Those options can set a few global network policies to be applied bastion-wide.
#
# dnsSupportLevel (integer between 0 and 2)
# DESC: If set to 0, The Bastion will never attempt to do DNS or reverse-DNS resolutions, and return an error if you request connection to a hostname instead of an IP. Use this if you know there's no working DNS in your environment and only use IPs everywhere.
# If set to 1, The Bastion will not attempt to do DNS or reverse-DNS resolutions unless you force it to (i.e. by requesting connection to a hostname instead of an IP). You may use this if for example you have well-known hostnames in /etc/hosts, but don't have a working DNS (which would imply that reverse-DNS resolutions will always fail).
# If set to 2, The Bastion will make the assumption that you have a working DNS setup, and will do DNS and reverse-DNS resolutions normally.
# DEFAULT: 2
"dnsSupportLevel": 2,
#
# allowedNetworks (array of strings (IPs and/or prefixes))
# DESC: Restricts egress connection attempts to those listed networks only. This is enforced at all times and can NOT be overridden by users. If you are lucky enough to have you own IP blocks, it's probably a good idea to list them here. An empty array means no restriction is applied.
# DEFAULT: []
Expand Down
8 changes: 8 additions & 0 deletions lib/perl/OVH/Bastion/allowdeny.inc
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ sub get_ip {
return R('ERR_INVALID_IP', msg => "IP $host version is not allowed");
}

if (OVH::Bastion::config('dnsSupportLevel')->value < 1) {
return R('ERR_DNS_DISABLED', msg => "DNS resolving is disabled on this bastion");
}

osh_debug("Trying to resolve '$host' because is_valid_ip() says it's not an IP");
my ($err, @res);
eval {
Expand Down Expand Up @@ -334,6 +338,10 @@ sub ip2host {
my $ip = shift;
my ($err, @sockaddr, $host);

if (OVH::Bastion::config('dnsSupportLevel')->value < 2) {
return R('ERR_DNS_DISABLED');
}

eval {
# ip => packedip. AI_PASSIVE: don't use dns, just build sockaddr
# can croak
Expand Down
39 changes: 18 additions & 21 deletions lib/perl/OVH/Bastion/configuration.inc
Original file line number Diff line number Diff line change
Expand Up @@ -211,47 +211,44 @@ sub load_configuration {
{name => 'accountMaxInactiveDays', min => 0, max => 365 * 5, default => 0},
{name => 'interactiveModeTimeout', min => 0, max => 86400 * 365, default => 15},
{name => 'interactiveModeProactiveMFAexpiration', min => 0, max => 86400, default => 900},
{name => 'dnsSupportLevel', min => 0, max => 2, default => 2},
)
{
if (not defined $C->{$o->{'name'}}) {
$C->{$o->{'name'}} = $o->{'default'};
push @errors, "Configuration error: missing option '" . $o->{'name'} . "', defaulting to " . $o->{'default'}
push @errors,
sprintf("Configuration error: missing option '%s', defaulting to %s", $o->{'name'}, $o->{'default'})
if $test;
}
if ($C->{$o->{'name'}} =~ /^(-?\d+)$/) {

# untaint
$C->{$o->{'name'}} = $1;
}
else {
push @errors,
"Configuration error: value of option '"
. $o->{'name'} . "' ('"
. $C->{$o->{'name'}}
. "') is not a number, defaulting to "
. $o->{'default'};
sprintf(
"Configuration error: value of option '%s' ('%s') is not a number, defaulting to %s",
$o->{'name'}, $C->{$o->{'name'}},
$o->{'default'}
);
$C->{$o->{'name'}} = $o->{'default'};
}
if ($C->{$o->{'name'}} > $o->{'max'}) {
push @errors,
"Configuration error: value of option '"
. $o->{'name'} . "' ("
. $C->{$o->{'name'}}
. ") is higher than allowed value ("
. $o->{'max'}
. "), defaulting to "
. $o->{'default'};
sprintf(
"Configuration error: value of option '%s' (%s) is higher than allowed value (%s), defaulting to %s",
$o->{'name'}, $C->{$o->{'name'}},
$o->{'max'}, $o->{'default'}
);
$C->{$o->{'name'}} = $o->{'default'};
}
elsif ($C->{$o->{'name'}} < $o->{'min'}) {
push @errors,
"Configuration error: value of option '"
. $o->{'name'} . "' ("
. $C->{$o->{'name'}}
. ") is lower than allowed value ("
. $o->{'min'}
. "), defaulting to "
. $o->{'default'};
sprintf(
"Configuration error: value of option '%s' (%s) is lower than allowed value (%s), defaulting to %s",
$o->{'name'}, $C->{$o->{'name'}},
$o->{'min'}, $o->{'default'}
);
$C->{$o->{'name'}} = $o->{'default'};
}
delete $unknownkeys{$o->{'name'}};
Expand Down
19 changes: 19 additions & 0 deletions tests/functional/tests.d/380-config-options.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# vim: set filetype=sh ts=4 sw=4 sts=4 et:
# shellcheck shell=bash
# shellcheck disable=SC2086,SC2016,SC2046
# below: convoluted way that forces shellcheck to source our caller
# shellcheck source=tests/functional/launch_tests_on_instance.sh
. "$(dirname "${BASH_SOURCE[0]}")"/dummy

testsuite_config_options()
{
configchg 's=^\\\\x22dnsSupportLevel\\\\x22.+=\\\\x22dnsSupportLevel\\\\x22:0,='

run a1_connect_nodns $a0 localhost
retvalmustbe 102
json .error_code KO_HOST_NOT_FOUND
contain 'DNS resolving is disabled'
}

testsuite_config_options
unset -f testsuite_config_options

0 comments on commit 7423f6a

Please sign in to comment.