Re: [refpolicy] Milter Mail Filters

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Christopher J. PeBenito wrote:
On Mon, 2008-06-09 at 16:25 +0100, Paul Howarth wrote:
Hi,

attached is a patch based on local policy I'm using on Fedora 9 to support two "milter" mail filter daemons in conjunction with sendmail, namely spamass-milter and milter-regex (I maintain the packages for both of these in Fedora).

I've taken the view that most milter applications will have similar requirements and so I've created a milter_template interface that contains most of what's needed, and then added the specifics that are needed on top of the generic stuff for each application.

However, as I'm by no means an selinux expert, there are a number of things I'm unsure about:

1. In a situation where sendmail is the running MTA on a system, what
is the difference between sendmail_t and system_mail_t?

2. MTAs other than sendmail (postfix comes to mind) can also use milters, but as I don't have any boxes running postfix, I don't know what I'd need to add to postfix policy to support milters.

3. Fedora 9 has an interface spamassassin_domtrans_spamc that I used
in my local policy. It doesn't appear to be present in refpolicy; what would be the right thing to use for a daemon calling spamc?

4. I cribbed the milter_port_t stuff from the only example I could
find, and it's probably wrong. What would be the correct way of defining
this?

5. Does the use of a template for these applications a sane way to do
it?

Paul.







plain text
document
attachment
(milters.patch)

Index: policy/modules/services/milters.te
===================================================================
--- policy/modules/services/milters.te  (revision 0)
+++ policy/modules/services/milters.te  (revision 0)
@@ -0,0 +1,44 @@
+policy_module(milters,0.0.7)
+
+require {
+       attribute port_type;
+}
+
+type milter_port_t, port_type;

This declaration would move to corenetwork

Moved.

+#============= milter-regex policy ==============
+milter_template(regex)

As I mentioned before, it doesn't look like a template is needed, unless
you think there will be many more milter domains.  Then put all the
declarations in a section.

There are plenty of milters out there - see http://www.milter.org/milters

Not sure what you mean by "put all the declarations in a section". The current version has very few declarations anyway now.

+# Config is in /etc/mail/milter-regex.conf
+mta_read_config(milter_regex_t)
+
+# The milter creates a socket in /var/spool/milter-regex/
+# for communication with sendmail
+files_search_spool(milter_regex_t)
+manage_sock_files_pattern(milter_regex_t,milter_regex_spool_t,milter_regex_spool_t)

If the /var/sool/milter-regex directory can be created by the milter,
then there should be a files_spool_filetrans().  If you think templates
are warranted, then it would seem that this should go into the template

That directory would be part of the package for the milter and wouldn't need to be created at runtime (it needs specific DAC permissions/ownership anyway).

+# It removes any existing socket (not owned by root) whilst running
as root
+# and then calls setgid() and setuid() to drop privileges
+allow milter_regex_t self:capability { setuid setgid dac_override };
+
+
+#============= spamass-milter policy ==============
+milter_template(spamass)
+
+# The milter creates a socket in /var/run/spamass-milter/
+# for communication with sendmail
+manage_files_pattern(milter_spamass_t,milter_spamass_var_run_t,milter_spamass_var_run_t)
+manage_sock_files_pattern(milter_spamass_t,milter_spamass_var_run_t,milter_spamass_var_run_t)
+
+# The main job of the milter is to pipe spam through spamc and act on
the result
+#
+# The spamassassin_domtrans_spamc interface in Fedora 9 ???
+#spamassassin_domtrans_spamc(milter_spamass_t)

This interface is part of the big patch merge from Fedora. I could split out the part needed by spamass-milter as a separate patch if that's helpful.

+# When used with -b or -B options, the milter invokes sendmail to
send mail
+# to a spamtrap address, using popen()
+corecmd_exec_shell(milter_spamass_t)
+corecmd_read_bin_symlinks(milter_spamass_t)
+corecmd_search_bin(milter_spamass_t)
+kernel_read_system_state(milter_spamass_t)
+mta_send_mail(milter_spamass_t)

Similar comments as the previous domain.

--- policy/modules/services/sendmail.te (revision 2710)
+++ policy/modules/services/sendmail.te (working copy)
@@ -112,6 +112,14 @@
 ')
optional_policy(`
+       milter_regex_stream_connect(sendmail_t)
+')
+
+optional_policy(`
+       milter_spamass_stream_connect(sendmail_t)
+')

Perhaps this should be a single milter_stream_connect_all(), since it
seems like sendmail would want to connect to all milters.

Indeed it does, and postfix too. I'm using typeattributes to achieve this now.

--- policy/modules/services/milters.fc  (revision 0)
+++ policy/modules/services/milters.fc  (revision 0)
@@ -0,0 +1,14 @@
+#================= contexts for milter-regex =================
+
+/usr/sbin/milter-regex         --      gen_context(system_u:object_r:milter_regex_exec_t,s0)
+
+/var/spool/milter-regex(/.*)?          gen_context(system_u:object_r:milter_regex_spool_t,s0)
+
+#================= contexts for spamass-milter =================
+
+/usr/sbin/spamass-milter       --      gen_context(system_u:object_r:milter_spamass_exec_t,s0)
+
+/var/run/spamass-milter
\.pid   --      gen_context(system_u:object_r:milter_spamass_var_run_t,s0)
+/var/run/spamass-milter(/.*)?          gen_context(system_u:object_r:milter_spamass_var_run_t,s0)

The comments don't really add anything here IMO.

OK, removed.

+template(`milter_template',`
[...]
+       # This type is for pidfiles etc.
+       type milter_$1_var_run_t;
+       files_type(milter_$1_var_run_t);
+
+       # This type is for spool/cache data etc.
+       type milter_$1_cache_t;
+       files_type(milter_$1_cache_t);
+
+       # This type is for spool/cache data etc.
+       type milter_$1_spool_t;
+       files_type(milter_$1_spool_t);
+
+       # This type is for state data etc.
+       type milter_$1_var_lib_t;
+       files_type(milter_$1_var_lib_t);

Most of these types aren't used, so they should be dropped.

I've merged most of the types together now.

+interface(`milter_spamass_stream_connect',`
+       gen_require(`
+               type milter_spamass_var_run_t, milter_spamass_t;
+       ')
+       stream_connect_pattern($1,milter_spamass_var_run_t,milter_spamass_var_run_t,milter_spamass_t)
+')
+

Missing a files_search_spool().  Interface name needs to be fixed [1].

I have two interfaces now, common to all milters:

milter_stream_connect
milter_getattr_socket_dir

I'll try claiming that "milter" is an abbreviation of "milters"; any suggestions for better predicate names?

+interface(`milter_spamass_rw_stream_sockets',`
+        gen_require(`
+                type milter_spamass_t;
+        ')
+
+       allow $1 milter_spamass_t:unix_stream_socket { read write };
+')

Interface naming fix.


+interface(`milter_regex_stream_connect',`
+       gen_require(`
+               type milter_regex_spool_t, milter_regex_t;
+       ')
+       stream_connect_pattern($1,milter_regex_spool_t,milter_regex_spool_t,milter_regex_t)
+')

Also missing a files_search_spool() and interface naming fix.

I'm now using milter_$1_data_dir_t in the interface, where this directory might live under /var/spool for some milters, /var/run for others etc. So I added files_search_spool() in the te file for the milter(s) that needed it (only).

Heavily revised patch attached. The individual milter policies are quite brief now (and there are plenty more that could be added), which I think justifies the template approach. No further changes should need to be made to the sendmail and postfix policies to support additional milters either.

Paul.
Index: policy/modules/kernel/corenetwork.te.in
===================================================================
--- policy/modules/kernel/corenetwork.te.in	(revision 2770)
+++ policy/modules/kernel/corenetwork.te.in	(working copy)
@@ -119,6 +119,7 @@
 type lrrd_port_t, port_type; dnl network_port(lrrd_port_t) # no defined portcon
 network_port(lmtp, tcp,24,s0, udp,24,s0)
 network_port(mail, tcp,2000,s0)
+type milter_port_t, port_type; dnl network_port(milter) # no defined portcon
 network_port(mmcc, tcp,5050,s0, udp,5050,s0)
 network_port(monopd, tcp,1234,s0)
 network_port(msnp, tcp,1863,s0, udp,1863,s0)
Index: policy/modules/services/milters.te
===================================================================
--- policy/modules/services/milters.te	(revision 0)
+++ policy/modules/services/milters.te	(revision 0)
@@ -0,0 +1,42 @@
+policy_module(milters,0.1.4)
+
+require {
+	attribute port_type;
+}
+
+#============= declarations ================
+
+# attributes common to all milters
+attribute milter_domains;
+attribute milter_socket_directories;
+attribute milter_socket_type;
+
+
+#============= milter-regex policy ==============
+milter_template(regex)
+
+# Config is in /etc/mail/milter-regex.conf
+mta_read_config(milter_regex_t)
+
+# The milter's socket directory lives under /var/spool
+files_search_spool(milter_regex_t)
+
+# It removes any existing socket (not owned by root) whilst running as root
+# and then calls setgid() and setuid() to drop privileges
+allow milter_regex_t self:capability { setuid setgid dac_override };
+
+
+#============= spamass-milter policy ==============
+milter_template(spamass)
+
+# The main job of the milter is to pipe spam through spamc and act on the result
+spamassassin_domtrans_spamc(milter_spamass_t)
+
+# When used with -b or -B options, the milter invokes sendmail to send mail
+# to a spamtrap address, using popen()
+corecmd_exec_shell(milter_spamass_t)
+corecmd_read_bin_symlinks(milter_spamass_t)
+corecmd_search_bin(milter_spamass_t)
+kernel_read_system_state(milter_spamass_t)
+mta_send_mail(milter_spamass_t)
+
Index: policy/modules/services/sendmail.te
===================================================================
--- policy/modules/services/sendmail.te	(revision 2770)
+++ policy/modules/services/sendmail.te	(working copy)
@@ -112,6 +112,10 @@
 ')
 
 optional_policy(`
+	milter_stream_connect(sendmail_t)
+')
+
+optional_policy(`
 	postfix_exec_master(sendmail_t)
 	postfix_read_config(sendmail_t)
 	postfix_search_spool(sendmail_t)
Index: policy/modules/services/milters.fc
===================================================================
--- policy/modules/services/milters.fc	(revision 0)
+++ policy/modules/services/milters.fc	(revision 0)
@@ -0,0 +1,13 @@
+/usr/sbin/milter-regex				--	gen_context(system_u:object_r:milter_regex_exec_t,s0)
+/var/spool/milter-regex				-d	gen_context(system_u:object_r:milter_regex_data_dir_t,s0)
+/var/spool/milter-regex/sock			-s	gen_context(system_u:object_r:milter_regex_socket_t,s0)
+/var/spool/milter-regex/.+				gen_context(system_u:object_r:milter_regex_data_t,s0)
+
+/usr/sbin/spamass-milter			--	gen_context(system_u:object_r:milter_spamass_exec_t,s0)
+/var/run/spamass-milter				-d	gen_context(system_u:object_r:milter_spamass_data_dir_t,s0)
+/var/run/spamass-milter\.pid			--	gen_context(system_u:object_r:milter_spamass_data_t,s0)
+/var/run/spamass-milter/spamass-milter\.sock	-s	gen_context(system_u:object_r:milter_spamass_socket_t,s0)
+/var/run/spamass-milter/.+				gen_context(system_u:object_r:milter_spamass_data_t,s0)
+/var/run/spamass-milter/postfix			-d	gen_context(system_u:object_r:milter_spamass_data_dir_t,s0)
+/var/run/spamass-milter/postfix/sock		-s	gen_context(system_u:object_r:milter_spamass_socket_t,s0)
+
Index: policy/modules/services/mta.te
===================================================================
--- policy/modules/services/mta.te	(revision 2770)
+++ policy/modules/services/mta.te	(working copy)
@@ -105,6 +105,9 @@
 	# postfix needs this for newaliases
 	files_getattr_tmp_dirs(system_mail_t)
 
+	# newaliases runs as system_mail_t when the sendmail initscript does a restart
+	milter_getattr_socket_dir(system_mail_t)
+
 	postfix_exec_master(system_mail_t)
 	postfix_read_config(system_mail_t)
 	postfix_search_spool(system_mail_t)
Index: policy/modules/services/milters.if
===================================================================
--- policy/modules/services/milters.if	(revision 0)
+++ policy/modules/services/milters.if	(revision 0)
@@ -0,0 +1,108 @@
+## <summary>Milter mail filters</summary>
+
+########################################
+## <summary>
+##	Create a set of derived types for various
+##	mail filter applications using the milter interface.
+## </summary>
+## <param name="milter_name">
+##	<summary>
+##	The name to be used for deriving type names.
+##	</summary>
+## </param>
+#
+template(`milter_template',`
+
+	# attributes common to all milters, plus port type for milter TCP sockets
+	gen_require(`
+		attribute milter_socket_directories, milter_socket_type, milter_domains;
+		type milter_port_t;
+	')
+
+	# Type that the milter application runs as
+	type milter_$1_t, milter_domains;
+	domain_type(milter_$1_t)
+	role system_r types milter_$1_t;
+
+	# Type for the executable file
+	type milter_$1_exec_t;
+	init_daemon_domain(milter_$1_t, milter_$1_exec_t)
+
+	# Type for the directory that the unix-domain socket for MTA
+	# communication will live in
+	type milter_$1_data_dir_t, milter_socket_directories;
+	files_type(milter_$1_data_dir_t)
+
+	# Type for the unix-domain socket for MTA communication
+	type milter_$1_socket_t, milter_socket_type;
+	files_type(milter_$1_socket_t);
+	filetrans_pattern(milter_$1_t,milter_$1_data_dir_t,milter_$1_socket_t,sock_file)
+
+	# Any other data the milter puts in a milter_data_dir_t directory
+	type milter_$1_data_t;
+	files_type(milter_$1_data_t);
+	filetrans_pattern(milter_$1_t,milter_$1_data_dir_t,milter_$1_data_t,{ dir file })
+
+	# Generic rules from policygentool
+	files_read_etc_files(milter_$1_t)
+	libs_use_ld_so(milter_$1_t)
+	libs_use_shared_libs(milter_$1_t)
+	miscfiles_read_localization(milter_$1_t)
+	sysnet_dns_name_resolve(milter_$1_t)
+	init_use_fds(milter_$1_t)
+	init_use_script_ptys(milter_$1_t)
+	domain_use_interactive_fds(milter_$1_t)
+
+	# Allow communication with MTA over a TCP socket
+	allow milter_$1_t milter_port_t:tcp_socket name_bind;
+	corenet_tcp_bind_generic_node(milter_$1_t)
+	allow milter_$1_t self:tcp_socket { listen accept };
+
+	# Allow communication with MTA over a unix-domain socket
+	manage_sock_files_pattern(milter_$1_t,milter_$1_data_dir_t,milter_$1_socket_t)
+
+	# Create other data files and directories in the socket directory
+	manage_files_pattern(milter_$1_t,milter_$1_data_dir_t,milter_$1_data_t)
+	manage_files_pattern(milter_$1_t,milter_$1_data_t,milter_$1_data_t)
+
+	# Things that most milters will need to do
+	allow milter_$1_t self:fifo_file rw_fifo_file_perms;
+	logging_send_syslog_msg(milter_$1_t)
+
+')
+
+########################################
+## <summary>
+##	MTA communication with milter sockets
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`milter_stream_connect',`
+	gen_require(`
+		attribute milter_socket_directories, milter_socket_type, milter_domains;
+	')
+	getattr_dirs_pattern($1,milter_socket_directories,milter_socket_directories)
+	stream_connect_pattern($1,milter_socket_directories,milter_socket_type,milter_domains)
+')
+
+########################################
+## <summary>
+##	Allow search of milter socket directory
+## </summary>
+## <param name="domain">
+##	<summary>
+##	Domain allowed access.
+##	</summary>
+## </param>
+#
+interface(`milter_getattr_socket_dir',`
+	gen_require(`
+		attribute milter_socket_directories;
+	')
+	getattr_dirs_pattern($1,milter_socket_directories,milter_socket_directories)
+')
+
Index: policy/modules/services/spamassassin.fc
===================================================================
--- policy/modules/services/spamassassin.fc	(revision 2770)
+++ policy/modules/services/spamassassin.fc	(working copy)
@@ -10,7 +10,6 @@
 /var/lib/spamassassin(/.*)?	gen_context(system_u:object_r:spamd_var_lib_t,s0)
 
 /var/run/spamassassin(/.*)?	gen_context(system_u:object_r:spamd_var_run_t,s0)
-/var/run/spamass-milter(/.*)?	gen_context(system_u:object_r:spamd_var_run_t,s0)
 
 /var/spool/spamassassin(/.*)?	gen_context(system_u:object_r:spamd_spool_t,s0)
 /var/spool/spamd(/.*)?		gen_context(system_u:object_r:spamd_spool_t,s0)
Index: policy/modules/services/postfix.te
===================================================================
--- policy/modules/services/postfix.te	(revision 2770)
+++ policy/modules/services/postfix.te	(working copy)
@@ -530,6 +530,10 @@
 	cyrus_stream_connect(postfix_smtp_t)
 ')
 
+optional_policy(`
+	milter_stream_connect(postfix_smtp_t)
+')
+
 ########################################
 #
 # Postfix smtpd local policy

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux