diff --git a/selinux/README.md b/selinux/README.md new file mode 100644 index 00000000..70f053d7 --- /dev/null +++ b/selinux/README.md @@ -0,0 +1,106 @@ +# Shadowsocks SELinux Policy + +## Prerequisites + +Install required SELinux development tools: +```bash +dnf upgrade && dnf install setools-console policycoreutils-python-utils selinux-policy-devel make +``` + +## Creating SELinux Policy + +### 1. Compile the policy + +```bash +make -f /usr/share/selinux/devel/Makefile shadowsocks.pp +``` + +### 2. Install the policy module + +```bash +semodule -i shadowsocks.pp +``` + +## Apply File Contexts + +### 1. Add file context mappings + +```bash +semanage fcontext -a -t shadowsocks_exec_t "/usr/bin/ssservice" +semanage fcontext -a -t shadowsocks_conf_t "/etc/shadowsocks(/.*)?" +semanage fcontext -a -t shadowsocks_unit_file_t "/usr/lib/systemd/system/ss-server@.*\.service" +``` + +### 2. Apply contexts to files + +```bash +restorecon -v /etc/systemd/system/ss-server@.service +restorecon -R /usr/bin/ssservice /etc/shadowsocks +``` + +### 3. Start the service + +```bash +systemctl start ss-server@main +``` + +### 4. Verify the policy is working + +```bash +# Check that shadowsocks is running in the correct domain +ps -eZ | grep ssservice +# Should show: system_u:system_r:shadowsocks_t:s0 (not unconfined_service_t) +``` + +## Troubleshooting +### Check for SELinux denials + +```bash +# View recent AVC denials +ausearch -m avc -ts recent | grep denied + +# Generate additional policy rules if needed +ausearch -m avc -ts recent | grep shadowsocks | audit2allow +``` + +### Update policy if needed + +If you need to add more permissions: + +```bash +# Edit shadowsocks.te file +# Recompile and update +make -f /usr/share/selinux/devel/Makefile shadowsocks.pp +semodule -u shadowsocks.pp +``` + +### Remove policy (if needed) + +```bash +# Remove file contexts first +semanage fcontext -d "/usr/bin/ssservice" +semanage fcontext -d "/etc/shadowsocks(/.*)?" +semanage fcontext -d "/usr/lib/systemd/system/ss-server@.*\.service" + +# Reset file labels +restorecon -F /usr/bin/ssservice +restorecon -RF /etc/shadowsocks + +# Remove the policy module +semodule -r shadowsocks +``` + +## Security Benefits + +This policy provides several security improvements over running shadowsocks as `unconfined_service_t`: + +- **Principle of least privilege**: Only grants necessary permissions +- **Network isolation**: Controls which ports and connections are allowed +- **File system protection**: Restricts file access to configuration and required system files +- **Process isolation**: Runs in a dedicated SELinux domain +- **Audit trail**: All access attempts are logged for security monitoring + +## Notes + +- The policy includes optional monitoring features (cgroup access, DNS watching) +- File contexts use equivalency rules between `/etc/systemd/system` and `/usr/lib/systemd/system` diff --git a/selinux/shadowsocks.fc b/selinux/shadowsocks.fc new file mode 100644 index 00000000..55e083e4 --- /dev/null +++ b/selinux/shadowsocks.fc @@ -0,0 +1,3 @@ +/usr/bin/ssservice -- gen_context(system_u:object_r:shadowsocks_exec_t,s0) +/etc/shadowsocks(/.*)? -- gen_context(system_u:object_r:shadowsocks_conf_t,s0) +/usr/lib/systemd/system/ss-server@.*\.service -- gen_context(system_u:object_r:shadowsocks_unit_file_t,s0) diff --git a/selinux/shadowsocks.te b/selinux/shadowsocks.te new file mode 100644 index 00000000..3a39b955 --- /dev/null +++ b/selinux/shadowsocks.te @@ -0,0 +1,62 @@ +policy_module(shadowsocks, 1.0.0) + +######################################## +# +# Declarations +# + +type shadowsocks_t; +type shadowsocks_exec_t; +init_daemon_domain(shadowsocks_t, shadowsocks_exec_t) + +type shadowsocks_conf_t; +files_config_file(shadowsocks_conf_t) + +type shadowsocks_unit_file_t; +systemd_unit_file(shadowsocks_unit_file_t) + +######################################## +# +# shadowsocks local policy +# + +# Domain transition rules +domain_auto_trans(init_t, shadowsocks_exec_t, shadowsocks_t) +allow init_t shadowsocks_t:process2 nnp_transition; + +# Allow shadowsocks to use its own executable as entrypoint +allow shadowsocks_t shadowsocks_exec_t:file { entrypoint ioctl lock }; + +# Network sockets +allow shadowsocks_t self:tcp_socket create_stream_socket_perms; +allow shadowsocks_t self:udp_socket create_socket_perms; +allow shadowsocks_t self:process signal_perms; + +# Configuration files +allow shadowsocks_t shadowsocks_conf_t:file read_file_perms; +allow shadowsocks_t shadowsocks_conf_t:dir list_dir_perms; + +# Network access +corenet_tcp_bind_generic_node(shadowsocks_t) +corenet_udp_bind_generic_node(shadowsocks_t) +corenet_tcp_connect_all_ports(shadowsocks_t) +corenet_tcp_bind_all_ports(shadowsocks_t) +corenet_udp_bind_all_ports(shadowsocks_t) + +# System access +kernel_read_system_state(shadowsocks_t) +dev_read_urand(shadowsocks_t) +files_read_etc_files(shadowsocks_t) +miscfiles_read_localization(shadowsocks_t) +logging_send_syslog_msg(shadowsocks_t) + +# Network configuration and DNS resolution +sysnet_read_config(shadowsocks_t) +sysnet_dns_name_resolve(shadowsocks_t) +allow shadowsocks_t net_conf_t:file { read_file_perms watch }; + +# Cgroup access for resource monitoring +fs_search_cgroup_dirs(shadowsocks_t) +fs_getattr_cgroup(shadowsocks_t) +allow shadowsocks_t cgroup_t:file { getattr open read }; +allow shadowsocks_t cgroup_t:dir { search getattr };