mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
Merge parser: add network inet mediation documentation to apparmor.d
This updates the man page for the recent inet mediation patch. This is an extension of MR 1202, it adds a patch that changes the anonymous ip address anon to be ip address none which is a better fit. This patch adds documentation of the recent network changes which extended all network rules to support access permissions, and added address and port matching for inet and inet6 families. Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com> MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1213 Approved-by: John Johansen <john@jjmx.net> Merged-by: John Johansen <john@jjmx.net>
This commit is contained in:
commit
ab9e6311f3
5 changed files with 94 additions and 18 deletions
|
@ -148,7 +148,14 @@ B<CAPABILITY LIST> = ( I<CAPABILITY> )+
|
|||
B<CAPABILITY> = (lowercase capability name without 'CAP_' prefix; see
|
||||
capabilities(7))
|
||||
|
||||
B<NETWORK RULE> = [ I<QUALIFIERS> ] 'network' [ I<DOMAIN> ] [ I<TYPE> | I<PROTOCOL> ]
|
||||
B<NETWORK RULE> = [ I<QUALIFIERS> ] 'network' [ I<NETWORK ACCESS EXPR> ] [ I<DOMAIN> ] [ I<TYPE> | I<PROTOCOL> ] [ I<NETWORK LOCAL EXPR> ] [ I<NETWORK PEER EXPR> ]
|
||||
|
||||
B<NETWORK ACCESS EXPR> = ( I<NETWORK ACCESS> | I<NETWORK ACCESS LIST> )
|
||||
|
||||
B<NETWORK ACCESS> = ( 'create' | 'bind' | 'listen' | 'accept' | 'connect' | 'shutdown' | 'getattr' | 'setattr' | 'getopt' | 'setopt' | 'send' | 'receive' | 'r' | 'w' | 'rw' )
|
||||
Some access modes are incompatible with some rules.
|
||||
|
||||
B<NETWORK ACCESS LIST> = '(' I<NETWORK ACCESS> ( [','] I<NETWORK ACCESS> )* ')'
|
||||
|
||||
B<DOMAIN> = ( 'unix' | 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' | 'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' | 'netbeui' | 'security' | 'key' | 'netlink' | 'packet' | 'ash' | 'econet' | 'atmsvc' | 'rds' | 'sna' | 'irda' | 'pppox' | 'wanpipe' | 'llc' | 'ib' | 'mpls' | 'can' | 'tipc' | 'bluetooth' | 'iucv' | 'rxrpc' | 'isdn' | 'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' | 'vsock' | 'kcm' | 'qipcrtr' | 'smc' | 'xdp' | 'mctp' ) ','
|
||||
|
||||
|
@ -156,6 +163,22 @@ B<TYPE> = ( 'stream' | 'dgram' | 'seqpacket' | 'rdm' | 'raw' | 'packet' )
|
|||
|
||||
B<PROTOCOL> = ( 'tcp' | 'udp' | 'icmp' )
|
||||
|
||||
B<NETWORK LOCAL EXPR> = ( I<NETWORK IP COND> | I<NETWORK PORT COND> )*
|
||||
Each cond can appear at most once.
|
||||
|
||||
B<NETWORK PEER EXPR> = 'peer' '=' '(' ( I<NETWORK IP COND> | I<NETWORK PORT COND> )+ ')'
|
||||
Each cond can appear at most once.
|
||||
|
||||
B<NETWORK IP COND> = 'ip' '=' ( 'none' | I<NETWORK IPV4> | I<NETWORK IPV6> )
|
||||
|
||||
B<NETWORK PORT COND> = 'port' '=' ( I<NETWORK PORT> )
|
||||
|
||||
B<NETWORK IPV4> = IPv4, represented by four 8-bit decimal numbers separated by '.'
|
||||
|
||||
B<NETWORK IPV6> = IPv6, represented by eight groups of four hexadecimal numbers separated by ':'. Shortened representation of contiguous zeros is allowed by using '::'
|
||||
|
||||
B<NETWORK PORT> = 16-bit number ranging from 0 to 65535
|
||||
|
||||
B<MOUNT RULE> = ( I<MOUNT> | I<REMOUNT> | I<UMOUNT> )
|
||||
|
||||
B<MOUNT> = [ I<QUALIFIERS> ] 'mount' [ I<MOUNT CONDITIONS> ] [ I<SOURCE FILEGLOB> ] [ '-E<gt>' [ I<MOUNTPOINT FILEGLOB> ]
|
||||
|
@ -912,11 +935,10 @@ and other operations that are typically reserved for the root user.
|
|||
|
||||
=head2 Network Rules
|
||||
|
||||
AppArmor supports simple coarse grained network mediation. The network
|
||||
rule restrict all socket(2) based operations. The mediation done is
|
||||
a coarse-grained check on whether a socket of a given type and family
|
||||
can be created, read, or written. There is no mediation based of port
|
||||
number or protocol beyond tcp, udp, and raw. Network netlink(7) rules may
|
||||
AppArmor supports simple coarse grained network mediation. The
|
||||
network rule restrict all socket(2) based operations. The mediation
|
||||
done is a coarse-grained check on whether a socket of a given type and
|
||||
family can be created, read, or written. Network netlink(7) rules may
|
||||
only specify type 'dgram' and 'raw'.
|
||||
|
||||
AppArmor network rules are accumulated so that the granted network
|
||||
|
@ -933,6 +955,48 @@ eg.
|
|||
network inet6 tcp, #allow access to tcp only for inet6 addresses
|
||||
network netlink raw, #allow access to AF_NETLINK SOCK_RAW
|
||||
|
||||
=head3 Network permissions
|
||||
|
||||
Network rule permissions are implied when a rule does not explicitly
|
||||
state an access list. By default if a rule does not have an access
|
||||
list all permissions that are compatible with the specified set of
|
||||
local and peer conditionals are implied.
|
||||
|
||||
The create, bind, listen, shutdown, getattr, setattr, getopt, and
|
||||
setopt permissions are local socket permissions. They are only applied
|
||||
to the local socket and can't be specified in rules that have a peer
|
||||
conditional. The accept permission applies to the combination of a
|
||||
local and peer socket. The connect, send, and receive permissions are
|
||||
peer socket permissions.
|
||||
|
||||
=head3 Mediation of inet/inet6 family
|
||||
|
||||
AppArmor supports fine grained mediation of the inet and inet6
|
||||
families by using the ip and port conditionals. The ip conditional
|
||||
accepts both IPv4 and IPv6 using the regular representation of four
|
||||
octets separated by '.' for IPv4 and eight groups of four hexadecimal
|
||||
numbers separated by ':' for IPv6. Contiguous leading zeros can be
|
||||
replaced by '::' once. On a connected socket, the sender and receiver
|
||||
don't need to be specified in the recvfrom and sendto system calls. In
|
||||
that case, and with unbounded sockets, the IP address is none, or
|
||||
unknown. Unknown or Unbound IP addresses are represented in policy by the
|
||||
'none' keyword. When the ip conditional is omitted, then all IP
|
||||
addresses will be allowed: IPv4, IPv6 and none. If INADDR_ANY or
|
||||
in6addr_any is used, then the ip conditional can be omitted or they
|
||||
can be represented by:
|
||||
|
||||
network ip=::, #allow in6addr_any
|
||||
network ip=0.0.0.0; #allow INADDR_ANY
|
||||
|
||||
The network rules support the specification of local and remote IP
|
||||
addresses and ports.
|
||||
|
||||
network ip=127.0.0.1 port=8080,
|
||||
network peer=(ip=10.139.15.23 port=8081),
|
||||
network ip=fd74:1820:b03a:b361::cf32 peer=(ip=fd74:1820:b03a:b361::a0f9),
|
||||
network port=8080 peer=(port=8081),
|
||||
network ip=127.0.0.1 port=8080 peer=(ip=10.139.15.23 port=8081),
|
||||
|
||||
=head2 Mount Rules
|
||||
|
||||
AppArmor supports mount mediation and allows specifying filesystem types and
|
||||
|
|
|
@ -360,8 +360,8 @@ bool network_rule::parse_port(ip_conds &entry)
|
|||
|
||||
bool network_rule::parse_address(ip_conds &entry)
|
||||
{
|
||||
if (strcmp(entry.sip, "anon") == 0) {
|
||||
entry.is_anonymous = true;
|
||||
if (strcmp(entry.sip, "none") == 0) {
|
||||
entry.is_none = true;
|
||||
return true;
|
||||
}
|
||||
entry.is_ip = true;
|
||||
|
@ -615,13 +615,13 @@ std::string gen_port_cond(uint16_t port)
|
|||
std::list<std::ostringstream> gen_all_ip_options(std::ostringstream &oss) {
|
||||
|
||||
std::list<std::ostringstream> all_streams;
|
||||
std::ostringstream anon, ipv4, ipv6;
|
||||
std::ostringstream none, ipv4, ipv6;
|
||||
int i;
|
||||
anon << oss.str();
|
||||
none << oss.str();
|
||||
ipv4 << oss.str();
|
||||
ipv6 << oss.str();
|
||||
|
||||
anon << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ANON_SIZE;
|
||||
none << "\\x" << std::setfill('0') << std::setw(2) << std::hex << NONE_SIZE;
|
||||
|
||||
/* add a byte containing the size of the following ip */
|
||||
ipv4 << "\\x" << std::setfill('0') << std::setw(2) << std::hex << IPV4_SIZE;
|
||||
|
@ -633,7 +633,7 @@ std::list<std::ostringstream> gen_all_ip_options(std::ostringstream &oss) {
|
|||
for (i = 0; i < 16; ++i)
|
||||
ipv6 << ".";
|
||||
|
||||
all_streams.push_back(std::move(anon));
|
||||
all_streams.push_back(std::move(none));
|
||||
all_streams.push_back(std::move(ipv4));
|
||||
all_streams.push_back(std::move(ipv6));
|
||||
|
||||
|
@ -657,7 +657,7 @@ bool network_rule::gen_ip_conds(Profile &prof, std::list<std::ostringstream> &st
|
|||
std::list<std::ostringstream> ip_streams;
|
||||
|
||||
for (auto &oss : streams) {
|
||||
if (entry.is_port && !(entry.is_ip && entry.is_anonymous)) {
|
||||
if (entry.is_port && !(entry.is_ip && entry.is_none)) {
|
||||
/* encode port type (privileged - 1, remote - 2, unprivileged - 0) */
|
||||
if (!is_peer && perms & AA_NET_BIND && entry.port < IPPORT_RESERVED)
|
||||
oss << "\\x01";
|
||||
|
@ -680,8 +680,8 @@ bool network_rule::gen_ip_conds(Profile &prof, std::list<std::ostringstream> &st
|
|||
if (entry.is_ip) {
|
||||
oss << gen_ip_cond(entry.ip);
|
||||
streams.push_back(std::move(oss));
|
||||
} else if (entry.is_anonymous) {
|
||||
oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ANON_SIZE;
|
||||
} else if (entry.is_none) {
|
||||
oss << "\\x" << std::setfill('0') << std::setw(2) << std::hex << NONE_SIZE;
|
||||
streams.push_back(std::move(oss));
|
||||
} else {
|
||||
streams.splice(streams.end(), gen_all_ip_options(oss));
|
||||
|
@ -928,7 +928,7 @@ static int cmp_ip_conds(ip_conds const &lhs, ip_conds const &rhs)
|
|||
res = null_strcmp(lhs.sport, rhs.sport);
|
||||
if (res)
|
||||
return res;
|
||||
return lhs.is_anonymous - rhs.is_anonymous;
|
||||
return lhs.is_none - rhs.is_none;
|
||||
}
|
||||
|
||||
static int cmp_network_map(std::unordered_map<unsigned int, std::pair<unsigned int, unsigned int>> lhs,
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
#define CMD_LISTEN 2
|
||||
#define CMD_OPT 4
|
||||
|
||||
#define ANON_SIZE 0
|
||||
#define NONE_SIZE 0
|
||||
#define IPV4_SIZE 1
|
||||
#define IPV6_SIZE 2
|
||||
|
||||
|
@ -132,7 +132,7 @@ public:
|
|||
uint16_t port;
|
||||
struct ip_address ip;
|
||||
|
||||
bool is_anonymous = false;
|
||||
bool is_none = false;
|
||||
|
||||
void free_conds() {
|
||||
if (sip)
|
||||
|
|
11
parser/tst/simple_tests/network/network_ok_44.sd
Normal file
11
parser/tst/simple_tests/network/network_ok_44.sd
Normal file
|
@ -0,0 +1,11 @@
|
|||
#
|
||||
#=DESCRIPTION network none ip conditional test
|
||||
#=EXRESULT PASS
|
||||
#
|
||||
/usr/bin/foo {
|
||||
network ip=none,
|
||||
network peer=(ip=none),
|
||||
network inet ip=none peer=(ip=none),
|
||||
network inet tcp ip=none peer=(ip=none),
|
||||
|
||||
}
|
|
@ -477,6 +477,7 @@ syntax_failure = (
|
|||
'network/network_ok_41.sd',
|
||||
'network/network_ok_42.sd',
|
||||
'network/network_ok_43.sd',
|
||||
'network/network_ok_44.sd',
|
||||
'network/perms/ok_accept_1.sd',
|
||||
'network/perms/ok_accept_2.sd',
|
||||
'network/perms/ok_attr_1.sd',
|
||||
|
|
Loading…
Add table
Reference in a new issue