Dropping radvd process privileges
radvd needs to run as root, but has the capability to drop privileges on
linux hosts. Currently, radvd process is not using this feature and
this can be considered a serious risk.
In addition, some distributions like SUSE, radvd process runs as a non
privileged user by default, causing radvd failure to daemonize
because it can't write the pid in the corresponding neutron folder and
break the IPv6 functionality.
This patch allows radvd process to run with the same user used by
neutron. In order to allow this, it changes the radvd config file
permissions to 444 because radvd doesn't allow that this file can be
writeable by self/group. The readonly mode is not a problem updating the
file because of the way the neutron_lib replace_file function handles
the files operations.
Closes-Bug: #1777922
Change-Id: Ic5d976ba71a966a537d1f31888f82997a7ccb0de
Signed-off-by: aojeagarcia <aojeagarcia@suse.com>
(cherry picked from commit 9f2b40f2ce
)
This commit is contained in:
parent
2a837f20eb
commit
e6c63513de
|
@ -13,6 +13,9 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pwd
|
||||||
|
|
||||||
from itertools import chain as iter_chain
|
from itertools import chain as iter_chain
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
@ -137,7 +140,10 @@ class DaemonMonitor(object):
|
||||||
max_rtr_adv_interval=self._agent_conf.max_rtr_adv_interval,
|
max_rtr_adv_interval=self._agent_conf.max_rtr_adv_interval,
|
||||||
network_mtu=int(network_mtu)))
|
network_mtu=int(network_mtu)))
|
||||||
|
|
||||||
file_utils.replace_file(radvd_conf, buf.getvalue())
|
contents = buf.getvalue()
|
||||||
|
LOG.debug("radvd config = %s", contents)
|
||||||
|
# radvd conf file can't be writeable by self/group
|
||||||
|
file_utils.replace_file(radvd_conf, contents, file_mode=0o444)
|
||||||
return radvd_conf
|
return radvd_conf
|
||||||
|
|
||||||
def _get_radvd_process_manager(self, callback=None):
|
def _get_radvd_process_manager(self, callback=None):
|
||||||
|
@ -151,6 +157,8 @@ class DaemonMonitor(object):
|
||||||
|
|
||||||
def _spawn_radvd(self, radvd_conf):
|
def _spawn_radvd(self, radvd_conf):
|
||||||
def callback(pid_file):
|
def callback(pid_file):
|
||||||
|
# drop radvd daemon privileges and run as the neutron user
|
||||||
|
radvd_user = pwd.getpwuid(os.geteuid()).pw_name
|
||||||
# we need to use -m syslog and f.e. not -m stderr (the default)
|
# we need to use -m syslog and f.e. not -m stderr (the default)
|
||||||
# or -m stderr_syslog so that radvd 2.0+ will close stderr and
|
# or -m stderr_syslog so that radvd 2.0+ will close stderr and
|
||||||
# exit after daemonization; otherwise, the current thread will
|
# exit after daemonization; otherwise, the current thread will
|
||||||
|
@ -159,6 +167,7 @@ class DaemonMonitor(object):
|
||||||
radvd_cmd = [RADVD_SERVICE_CMD,
|
radvd_cmd = [RADVD_SERVICE_CMD,
|
||||||
'-C', '%s' % radvd_conf,
|
'-C', '%s' % radvd_conf,
|
||||||
'-p', '%s' % pid_file,
|
'-p', '%s' % pid_file,
|
||||||
|
'-u', '%s' % radvd_user,
|
||||||
'-m', 'syslog']
|
'-m', 'syslog']
|
||||||
return radvd_cmd
|
return radvd_cmd
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ from neutron.conf.agent.l3 import ha as ha_conf
|
||||||
from neutron.conf import common as base_config
|
from neutron.conf import common as base_config
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
from neutron.tests.common import l3_test_common
|
from neutron.tests.common import l3_test_common
|
||||||
|
from neutron.tests.unit.agent.linux.test_utils import FakeUser
|
||||||
|
|
||||||
_uuid = uuidutils.generate_uuid
|
_uuid = uuidutils.generate_uuid
|
||||||
HOSTNAME = 'myhost'
|
HOSTNAME = 'myhost'
|
||||||
|
@ -2767,7 +2768,9 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
||||||
|
|
||||||
self.assertFalse(ri.remove_floating_ip.called)
|
self.assertFalse(ri.remove_floating_ip.called)
|
||||||
|
|
||||||
def test_spawn_radvd(self):
|
@mock.patch('os.geteuid', return_value='490')
|
||||||
|
@mock.patch('pwd.getpwuid', return_value=FakeUser('neutron'))
|
||||||
|
def test_spawn_radvd(self, geteuid, getpwuid):
|
||||||
router = l3_test_common.prepare_router_data(ip_version=6)
|
router = l3_test_common.prepare_router_data(ip_version=6)
|
||||||
|
|
||||||
conffile = '/fake/radvd.conf'
|
conffile = '/fake/radvd.conf'
|
||||||
|
@ -2805,6 +2808,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
||||||
cmd = _join(*cmd)
|
cmd = _join(*cmd)
|
||||||
self.assertIn(_join('-C', conffile), cmd)
|
self.assertIn(_join('-C', conffile), cmd)
|
||||||
self.assertIn(_join('-p', pidfile), cmd)
|
self.assertIn(_join('-p', pidfile), cmd)
|
||||||
|
self.assertIn(_join('-u', 'neutron'), cmd)
|
||||||
self.assertIn(_join('-m', 'syslog'), cmd)
|
self.assertIn(_join('-m', 'syslog'), cmd)
|
||||||
|
|
||||||
def test_generate_radvd_mtu_conf(self):
|
def test_generate_radvd_mtu_conf(self):
|
||||||
|
|
Loading…
Reference in New Issue