I'm currently trying to write a policy for the nginx webserver. As i am a beginner i would like to know if somebody could give me some advices to avoid common mistakes. To write this policy i've followed this steps : - generate a policy with policygentool - analyse logs to adapt the policy - apply some more changes to fit my needs - run the nginx webserver with the new policy loaded.
For instant, i am running a simple website that serves only static content, i have no "avc denied" in logs. How could i fully test the policy in order to validate it ? How could i improve the policy ?
Here is my type enforcement file :
#### nginx.te #### policy_module(nginx,1.0.0)
require { type sysctl_t; type sysctl_kernel_t; type node_t; }
######################################## # # Declarations #
type nginx_t; type nginx_exec_t; domain_type(nginx_t) init_daemon_domain(nginx_t, nginx_exec_t)
# configuration files # TODO: use files_config_file instead files_type type nginx_conf_t; files_type(nginx_conf_t)
# pid files type nginx_var_run_t; files_pid_file(nginx_var_run_t)
# log files type nginx_var_log_t; logging_log_file(nginx_var_log_t)
# var/lib files type nginx_var_lib_t; files_type(nginx_var_lib_t)
######################################## # # nginx local policy # # Check in /etc/selinux/refpolicy/include for macros to use instead of allow rules
# Some common macros (you might be able to remove some) files_search_etc(nginx_t) libs_use_ld_so(nginx_t) libs_use_shared_libs(nginx_t) miscfiles_read_localization(nginx_t) ## internal communication is often done using fifo and unix sockets. allow nginx_t self:fifo_file { read write }; allow nginx_t self:unix_stream_socket create_stream_socket_perms;
# conf files allow nginx_t nginx_conf_t:dir list_dir_perms; allow nginx_t nginx_conf_t:file read_file_perms; allow nginx_t nginx_conf_t:lnk_file read_lnk_file_perms; files_etc_filetrans(nginx_t,nginx_conf_t, { file dir })
# pid file allow nginx_t nginx_var_run_t:file manage_file_perms; allow nginx_t nginx_var_run_t:sock_file manage_file_perms; allow nginx_t nginx_var_run_t:dir rw_dir_perms; files_pid_filetrans(nginx_t,nginx_var_run_t, { file sock_file })
# log files allow nginx_t nginx_var_log_t:file { create_file_perms append }; allow nginx_t nginx_var_log_t:sock_file create_file_perms; allow nginx_t nginx_var_log_t:dir { rw_dir_perms setattr }; logging_log_filetrans(nginx_t,nginx_var_log_t,{ sock_file file dir })
# var/lib files for nginx allow nginx_t nginx_var_lib_t:file create_file_perms; allow nginx_t nginx_var_lib_t:sock_file create_file_perms; allow nginx_t nginx_var_lib_t:dir { search_dir_perms create_dir_perms }; files_var_lib_filetrans(nginx_t,nginx_var_lib_t, { file dir sock_file })
## Networking basics (adjust to your needs!) sysnet_dns_name_resolve(nginx_t) corenet_tcp_sendrecv_all_if(nginx_t) corenet_tcp_sendrecv_all_nodes(nginx_t) corenet_tcp_sendrecv_all_ports(nginx_t) #corenet_non_ipsec_sendrecv(nginx_t) corenet_all_recvfrom_unlabeled(nginx_t) corenet_tcp_connect_http_port(nginx_t) #corenet_tcp_connect_all_ports(nginx_t) ## if it is a network daemon, consider these: #corenet_tcp_bind_all_ports(nginx_t) #corenet_tcp_bind_all_nodes(nginx_t) corenet_tcp_bind_http_port(nginx_t) corenet_tcp_bind_http_cache_port(nginx_t) allow nginx_t self:tcp_socket { listen accept }; allow nginx_t node_t:tcp_socket node_bind;
# Init script handling init_use_fds(nginx_t) init_use_script_ptys(nginx_t) domain_use_interactive_fds(nginx_t)
# System allow nginx_t self:capability { setuid net_bind_service setgid dac_override };
kernel_read_kernel_sysctls(nginx_t) #allow nginx_t sysctl_kernel_t:dir search; #allow nginx_t sysctl_kernel_t:file read; #allow nginx_t sysctl_t:dir search; allow nginx_t etc_t:dir search;
# Access apache content apache_manage_sys_content(nginx_t) apache_search_sys_content(nginx_t) apache_read_sys_content(nginx_t)
files_search_mnt(nginx_t) files_read_etc_files(nginx_t) files_read_usr_files(nginx_t) miscfiles_read_certs(nginx_t)
-- Jérémy
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/14/2011 10:07 AM, Mossburg wrote:
I'm currently trying to write a policy for the nginx webserver.
It is probably better to make this webserver run in the httpd_t domain.
That means that you would have to add file context specifications for some files included with the nginx package:
its executable file, configuration file, pid file, log, lib and init script file.
You did not include your nginx.fc file and so i cannot suggest these changes.
Ofcourse you can also do it your way and write policy from scratch but doing this for a web server is probably not the best idea. webservers can be pretty complex and can be configured in many ways.
So again, i would suggest trying to run nginx in the existing httpd_t domain instead so that httpd's proven policy applies to nginx, Saves work/time.
As i am a beginner i would like to know if somebody could give me some advices to avoid common mistakes. To write this policy i've followed this steps :
- generate a policy with policygentool
- analyse logs to adapt the policy
- apply some more changes to fit my needs
- run the nginx webserver with the new policy loaded.
For instant, i am running a simple website that serves only static content, i have no "avc denied" in logs. How could i fully test the policy in order to validate it ? How could i improve the policy ?
Here is my type enforcement file :
#### nginx.te #### policy_module(nginx,1.0.0)
require { type sysctl_t; type sysctl_kernel_t; type node_t; }
######################################## # # Declarations #
type nginx_t; type nginx_exec_t; domain_type(nginx_t) init_daemon_domain(nginx_t, nginx_exec_t)
# configuration files # TODO: use files_config_file instead files_type type nginx_conf_t; files_type(nginx_conf_t)
# pid files type nginx_var_run_t; files_pid_file(nginx_var_run_t)
# log files type nginx_var_log_t; logging_log_file(nginx_var_log_t)
# var/lib files type nginx_var_lib_t; files_type(nginx_var_lib_t)
######################################## # # nginx local policy # # Check in /etc/selinux/refpolicy/include for macros to use instead of allow rules
# Some common macros (you might be able to remove some) files_search_etc(nginx_t) libs_use_ld_so(nginx_t) libs_use_shared_libs(nginx_t) miscfiles_read_localization(nginx_t) ## internal communication is often done using fifo and unix sockets. allow nginx_t self:fifo_file { read write }; allow nginx_t self:unix_stream_socket create_stream_socket_perms;
# conf files allow nginx_t nginx_conf_t:dir list_dir_perms; allow nginx_t nginx_conf_t:file read_file_perms; allow nginx_t nginx_conf_t:lnk_file read_lnk_file_perms; files_etc_filetrans(nginx_t,nginx_conf_t, { file dir })
# pid file allow nginx_t nginx_var_run_t:file manage_file_perms; allow nginx_t nginx_var_run_t:sock_file manage_file_perms; allow nginx_t nginx_var_run_t:dir rw_dir_perms; files_pid_filetrans(nginx_t,nginx_var_run_t, { file sock_file })
# log files allow nginx_t nginx_var_log_t:file { create_file_perms append }; allow nginx_t nginx_var_log_t:sock_file create_file_perms; allow nginx_t nginx_var_log_t:dir { rw_dir_perms setattr }; logging_log_filetrans(nginx_t,nginx_var_log_t,{ sock_file file dir })
# var/lib files for nginx allow nginx_t nginx_var_lib_t:file create_file_perms; allow nginx_t nginx_var_lib_t:sock_file create_file_perms; allow nginx_t nginx_var_lib_t:dir { search_dir_perms create_dir_perms }; files_var_lib_filetrans(nginx_t,nginx_var_lib_t, { file dir sock_file })
## Networking basics (adjust to your needs!) sysnet_dns_name_resolve(nginx_t) corenet_tcp_sendrecv_all_if(nginx_t) corenet_tcp_sendrecv_all_nodes(nginx_t) corenet_tcp_sendrecv_all_ports(nginx_t) #corenet_non_ipsec_sendrecv(nginx_t) corenet_all_recvfrom_unlabeled(nginx_t) corenet_tcp_connect_http_port(nginx_t) #corenet_tcp_connect_all_ports(nginx_t) ## if it is a network daemon, consider these: #corenet_tcp_bind_all_ports(nginx_t) #corenet_tcp_bind_all_nodes(nginx_t) corenet_tcp_bind_http_port(nginx_t) corenet_tcp_bind_http_cache_port(nginx_t) allow nginx_t self:tcp_socket { listen accept }; allow nginx_t node_t:tcp_socket node_bind;
# Init script handling init_use_fds(nginx_t) init_use_script_ptys(nginx_t) domain_use_interactive_fds(nginx_t)
# System allow nginx_t self:capability { setuid net_bind_service setgid dac_override };
kernel_read_kernel_sysctls(nginx_t) #allow nginx_t sysctl_kernel_t:dir search; #allow nginx_t sysctl_kernel_t:file read; #allow nginx_t sysctl_t:dir search; allow nginx_t etc_t:dir search;
# Access apache content apache_manage_sys_content(nginx_t) apache_search_sys_content(nginx_t) apache_read_sys_content(nginx_t)
files_search_mnt(nginx_t) files_read_etc_files(nginx_t) files_read_usr_files(nginx_t) miscfiles_read_certs(nginx_t)
-- Jérémy -- selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/14/2011 10:07 AM, Mossburg wrote:
I'm currently trying to write a policy for the nginx webserver. As i am a beginner i would like to know if somebody could give me some advices to avoid common mistakes. To write this policy i've followed this steps :
- generate a policy with policygentool
- analyse logs to adapt the policy
- apply some more changes to fit my needs
- run the nginx webserver with the new policy loaded.
For instant, i am running a simple website that serves only static content, i have no "avc denied" in logs. How could i fully test the policy in order to validate it ? How could i improve the policy ?
Test it, test configurations, and use that to improve the policy. Writing (good) policy for a particular app requires that you are familiar with the app and its possible configurations. webservers can be configured in many ways and have many options. A good policy protects/restricts the app from defined security threats without causing loss of functionality in the application.
The exising apache policy module has been tested pretty thoroughly and was designed by people with a good understanding of web servers. the policy has many years of exposure. Studying this policy can be helpful and inspire.
But again, why re-invent the wheel when this is not strictly required. Instead run the nginx webserver in the httpd_t domain and benefit of proven technology instead.
Here is my type enforcement file :
#### nginx.te #### policy_module(nginx,1.0.0)
require { type sysctl_t; type sysctl_kernel_t; type node_t; }
######################################## # # Declarations #
type nginx_t; type nginx_exec_t; domain_type(nginx_t) init_daemon_domain(nginx_t, nginx_exec_t)
# configuration files # TODO: use files_config_file instead files_type type nginx_conf_t; files_type(nginx_conf_t)
# pid files type nginx_var_run_t; files_pid_file(nginx_var_run_t)
# log files type nginx_var_log_t; logging_log_file(nginx_var_log_t)
# var/lib files type nginx_var_lib_t; files_type(nginx_var_lib_t)
######################################## # # nginx local policy # # Check in /etc/selinux/refpolicy/include for macros to use instead of allow rules
# Some common macros (you might be able to remove some) files_search_etc(nginx_t) libs_use_ld_so(nginx_t) libs_use_shared_libs(nginx_t) miscfiles_read_localization(nginx_t) ## internal communication is often done using fifo and unix sockets. allow nginx_t self:fifo_file { read write }; allow nginx_t self:unix_stream_socket create_stream_socket_perms;
# conf files allow nginx_t nginx_conf_t:dir list_dir_perms; allow nginx_t nginx_conf_t:file read_file_perms; allow nginx_t nginx_conf_t:lnk_file read_lnk_file_perms; files_etc_filetrans(nginx_t,nginx_conf_t, { file dir })
# pid file allow nginx_t nginx_var_run_t:file manage_file_perms; allow nginx_t nginx_var_run_t:sock_file manage_file_perms; allow nginx_t nginx_var_run_t:dir rw_dir_perms; files_pid_filetrans(nginx_t,nginx_var_run_t, { file sock_file })
# log files allow nginx_t nginx_var_log_t:file { create_file_perms append }; allow nginx_t nginx_var_log_t:sock_file create_file_perms; allow nginx_t nginx_var_log_t:dir { rw_dir_perms setattr }; logging_log_filetrans(nginx_t,nginx_var_log_t,{ sock_file file dir })
# var/lib files for nginx allow nginx_t nginx_var_lib_t:file create_file_perms; allow nginx_t nginx_var_lib_t:sock_file create_file_perms; allow nginx_t nginx_var_lib_t:dir { search_dir_perms create_dir_perms }; files_var_lib_filetrans(nginx_t,nginx_var_lib_t, { file dir sock_file })
## Networking basics (adjust to your needs!) sysnet_dns_name_resolve(nginx_t) corenet_tcp_sendrecv_all_if(nginx_t) corenet_tcp_sendrecv_all_nodes(nginx_t) corenet_tcp_sendrecv_all_ports(nginx_t) #corenet_non_ipsec_sendrecv(nginx_t) corenet_all_recvfrom_unlabeled(nginx_t) corenet_tcp_connect_http_port(nginx_t) #corenet_tcp_connect_all_ports(nginx_t) ## if it is a network daemon, consider these: #corenet_tcp_bind_all_ports(nginx_t) #corenet_tcp_bind_all_nodes(nginx_t) corenet_tcp_bind_http_port(nginx_t) corenet_tcp_bind_http_cache_port(nginx_t) allow nginx_t self:tcp_socket { listen accept }; allow nginx_t node_t:tcp_socket node_bind;
# Init script handling init_use_fds(nginx_t) init_use_script_ptys(nginx_t) domain_use_interactive_fds(nginx_t)
# System allow nginx_t self:capability { setuid net_bind_service setgid dac_override };
kernel_read_kernel_sysctls(nginx_t) #allow nginx_t sysctl_kernel_t:dir search; #allow nginx_t sysctl_kernel_t:file read; #allow nginx_t sysctl_t:dir search; allow nginx_t etc_t:dir search;
# Access apache content apache_manage_sys_content(nginx_t) apache_search_sys_content(nginx_t) apache_read_sys_content(nginx_t)
files_search_mnt(nginx_t) files_read_etc_files(nginx_t) files_read_usr_files(nginx_t) miscfiles_read_certs(nginx_t)
-- Jérémy -- selinux mailing list selinux@lists.fedoraproject.org https://admin.fedoraproject.org/mailman/listinfo/selinux
selinux@lists.fedoraproject.org