From: pebenito@ieee.org (Chris PeBenito) Date: Wed, 31 Aug 2016 19:02:05 -0400 Subject: [refpolicy] Understanding SELinux Network Permissions In-Reply-To: References: Message-ID: <1a13fe2e-62ed-20b3-5af4-3d66fca1e519@ieee.org> To: refpolicy@oss.tresys.com List-Id: refpolicy.oss.tresys.com On 08/31/16 15:36, Naftuli Tzvi Kay via refpolicy wrote: > Networking permissions have always been fairly difficult for me to > understand in SELinux. > > My current understanding follows. The permissions in layers are as > follows for a client that wants to connect to a specific TCP port: > > 1. Domain must be able to create/open/read/write its own TCP socket, > which is accomplished like so: > > allow $domain_type self:tcp_socket create_stream_socket_perms; > > Now the domain can open a TCP socket but can't connect it to anything. > Also, opening a TCP socket does not mean the same thing as binding > (listening on a port as a server process). > > 2. Next, we have to grant it access to sending and receiving on a > network interface: > > # corenet_tcp_sendrecv_generic_if > allow $domain_type $net_interface_type:netif { tcp_send tcp_recv > egress ingress }; > > Now the process can both open its TCP client connection and send/recv > TCP packets on the given network interface, but can't send/recv those > packets to/from any hosts (including localhost probably). > > 3. Next, we grant access for it to be able to send/recv to given nodes: > > # corenet_tcp_sendrecv_generic_node > allow $domain_type $node_type:node { tcp_send tcp_recv sendto recvfrom }; > > It can now send/receive TCP packets to and from the given node, which > represents a host on the network. node_lo_t could be 127.0.0.1/32, for > instance, and you'd still need this permission to send/recv packets > from localhost. > > So far it can open a client socket, read/write on that socket, > send/receive packets from a given network interface, send/receive > packets from a given network host (node), but it can't connect to or > send/receive anything due to port restrictions. > > 4. We now grant it access to connect and send/recv packets to a given port: > > # corenet_tcp_sendrecv_generic_port > allow $domain_type $port_type:tcp_socket { send_msg recv_msg }; > # corenet_tcp_connect_generic_port > allow $domain_type $port_type:tcp_socket name_connect; > > Now it can fully send/receive packets to arbitrary hosts on arbitrary > ports over TCP. > > ----------------------- > > Is my above understanding correct? In the example of a server, how do > permissions differ? Can I have a server listen to a port without being > able to be a TCP client and connect to other ports? Not exactly. Most of the node/netif permissions are no longer checked as those old mechanisms have been replaced. This is a high level summary for TCP and UDP: 1. in all cases, you need the socket access like in #1 above, plus name_bind on the port type if you're a server and name_connect on the port type for TCP socket connections. 2. node_bind on the node, if you're a binding 3. send/receive on packet class, only if you have SECMARK rules loaded or network_peer_controls policycap enabled 4. If you have labeled networking configured or network_peer_controls policycap enabled: * node: sendto recvfrom * netif: ingress egress * peer: recv Other protocols, depending on what they are, don't have as many checks. -- Chris PeBenito