diff --git a/etc/ovn-bgp-agent/rootwrap.conf b/etc/ovn-bgp-agent/rootwrap.conf new file mode 100644 index 00000000..675fa64c --- /dev/null +++ b/etc/ovn-bgp-agent/rootwrap.conf @@ -0,0 +1,27 @@ +# Configuration for ovn-bgp-agent-rootwrap +# This file should be owned by (and only-writeable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writeable by root ! +filters_path=/etc/ovn-bgp-agent/rootwrap.d,/usr/share/ovn-bgp-agent/rootwrap + +# List of directories to search executables in, in case filters do not +# explicitely specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writeable by root ! +exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin + +# Enable logging to syslog +# Default value is False +use_syslog=False + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=syslog + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=ERROR diff --git a/etc/ovn-bgp-agent/rootwrap.d/rootwrap.filters b/etc/ovn-bgp-agent/rootwrap.d/rootwrap.filters new file mode 100644 index 00000000..da3cc0cd --- /dev/null +++ b/etc/ovn-bgp-agent/rootwrap.d/rootwrap.filters @@ -0,0 +1,13 @@ +# ovn-bgp-agent-rootwrap command filters for scripts +# This file should be owned by (and only-writable by) the root user + +[Filters] +# privileged/__init__.py: priv_context.PrivContext(default) +# This line ties the superuser privs with the config files, context name, +# and (implicitly) the actual python code invoked. +privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, ovn_bgp_agent.privileged.default, --privsep_sock_path, /tmp/.* + +ovs-vsctl: CommandFilter, ovs-vsctl, root +sysctl: CommandFilter, sysctl, root +ip: IpFilter, ip, root +vtysh: CommandFilter, vtysh, root diff --git a/ovn_bgp_agent/agent.py b/ovn_bgp_agent/agent.py index 4a72281a..c62e717d 100644 --- a/ovn_bgp_agent/agent.py +++ b/ovn_bgp_agent/agent.py @@ -72,6 +72,7 @@ class BGPAgent(service.Service, periodic_task.PeriodicTasks, def start(): config.init(sys.argv[1:]) config.setup_logging() + config.setup_privsep() bgp_agent_launcher = service.launch(config.CONF, BGPAgent()) bgp_agent_launcher.wait() diff --git a/ovn_bgp_agent/config.py b/ovn_bgp_agent/config.py index 122317c9..5c157245 100644 --- a/ovn_bgp_agent/config.py +++ b/ovn_bgp_agent/config.py @@ -12,8 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import shlex + from oslo_config import cfg from oslo_log import log as logging +from oslo_privsep import priv_context LOG = logging.getLogger(__name__) @@ -65,8 +68,40 @@ agent_opts = [ 'default 4789 is being used.'), ] +root_helper_opts = [ + cfg.StrOpt('root_helper', default='sudo', + help=("Root helper application. " + "Use 'sudo ovn-bgp-agent-rootwrap " + "/etc/ovn-bgp-agent/rootwrap.conf' to use the real " + "root filter facility. Change to 'sudo' to skip the " + "filtering and just run the command directly.")), + cfg.BoolOpt('use_helper_for_ns_read', + default=True, + help=("Use the root helper when listing the namespaces on a " + "system. This may not be required depending on the " + "security configuration. If the root helper is " + "not required, set this to False for a performance " + "improvement.")), + # We can't just use root_helper=sudo ovn-bgp-agent-rootwrap-daemon $cfg + # because it isn't appropriate for long-lived processes spawned with + # create_process. Having a bool use_rootwrap_daemon option precludes + # specifying the rootwrap daemon command, which may be necessary for Xen? + cfg.StrOpt('root_helper_daemon', + help=(""" +Root helper daemon application to use when possible. + +Use 'sudo ovn-bgp-agent-rootwrap-daemon /etc/ovn-bgp-agent/rootwrap.conf' +to run rootwrap in "daemon mode" which has been reported to improve +performance at scale. For more information on running rootwrap in +"daemon mode", see: + +https://docs.openstack.org/oslo.rootwrap/latest/user/usage.html#daemon-mode +""")), +] + CONF = cfg.CONF CONF.register_opts(agent_opts) +CONF.register_opts(root_helper_opts, "AGENT") logging.register_options(CONF) @@ -79,3 +114,11 @@ def setup_logging(): logging.setup(CONF, 'bgp-agent') logging.set_defaults(default_log_levels=logging.get_default_log_levels()) LOG.info("Logging enabled!") + + +def get_root_helper(conf): + return conf.AGENT.root_helper + + +def setup_privsep(): + priv_context.init(root_helper=shlex.split(get_root_helper(cfg.CONF))) diff --git a/setup.cfg b/setup.cfg index 40230053..0870ce37 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,10 +23,16 @@ classifier = [files] packages = ovn_bgp_agent +data_files = + etc/ovn-bgp-agent = + etc/ovn-bgp-agent/rootwrap.conf + etc/ovn-bgp-agent/rootwrap.d = etc/ovn-bgp-agent/rootwrap.d/* [entry_points] console_scripts = ovn-bgp-agent = ovn_bgp_agent.cmd.agent:start + ovn-bgp-agent-rootwrap = oslo_rootwrap.cmd:main + ovn-bgp-agent-rootwrap-daemon = oslo_rootwrap.cmd:daemon ovn_bgp_agent.drivers = ovn_bgp_driver = ovn_bgp_agent.drivers.openstack.ovn_bgp_driver:OVNBGPDriver