From: Paul Howarth <paul@city-fan.org>
To: "Christopher J. PeBenito" <cpebenito@tresys.com>
Cc: SE Linux <selinux@tycho.nsa.gov>
Subject: Re: [refpolicy] Milter Mail Filters
Date: Tue, 05 Aug 2008 11:03:51 +0100 [thread overview]
Message-ID: <48982587.30605@city-fan.org> (raw)
In-Reply-To: <1216385922.21191.125.camel@gorn>
[-- Attachment #1: Type: text/plain, Size: 8346 bytes --]
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.
[-- Attachment #2: milters.patch --]
[-- Type: text/plain, Size: 9029 bytes --]
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
next prev parent reply other threads:[~2008-08-05 10:04 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-09 15:25 [refpolicy] Milter Mail Filters Paul Howarth
2008-06-13 12:51 ` Paul Howarth
2008-06-13 14:23 ` Christopher J. PeBenito
2008-06-13 17:30 ` Paul Howarth
2008-07-18 12:58 ` Christopher J. PeBenito
2008-08-05 10:03 ` Paul Howarth [this message]
2008-09-05 13:26 ` Christopher J. PeBenito
2008-09-09 16:15 ` Paul Howarth
2008-09-22 12:27 ` Paul Howarth
2008-10-06 14:12 ` Christopher J. PeBenito
2008-10-08 13:05 ` Paul Howarth
2008-10-08 19:22 ` Christopher J. PeBenito
2008-10-10 18:24 ` Paul Howarth
2008-11-06 15:09 ` Christopher J. PeBenito
2008-11-06 15:24 ` Paul Howarth
2008-11-14 15:26 ` Christopher J. PeBenito
2008-11-17 15:05 ` Paul Howarth
2008-11-24 14:11 ` Christopher J. PeBenito
2008-11-24 14:34 ` Paul Howarth
2008-11-24 15:17 ` Christopher J. PeBenito
2008-11-24 16:07 ` Paul Howarth
2008-11-24 17:47 ` Christopher J. PeBenito
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48982587.30605@city-fan.org \
--to=paul@city-fan.org \
--cc=cpebenito@tresys.com \
--cc=selinux@tycho.nsa.gov \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.