Add the ability to associate ipfw rules with a specific prison ID.
Since the only thing truly unique about a prison is it's ID, I figured this would be the most granular way of handling this. This commit makes the following changes: - Adds tokenizing and parsing for the ``jail'' command line option to the ipfw(8) userspace utility. - Append the ipfw opcode list with O_JAIL. - While Iam here, add a comment informing others that if they want to add additional opcodes, they should append them to the end of the list to avoid ABI breakage. - Add ``fw_prid'' to the ipfw ucred cache structure. - When initializing ucred cache, if the process is jailed, set fw_prid to the prison ID, otherwise set it to -1. - Update man page to reflect these changes. This change was a strong motivator behind the ucred caching mechanism in ipfw. A sample usage of this new functionality could be: ipfw add count ip from any to any jail 2 It should be noted that because ucred based constraints are only implemented for TCP and UDP packets, the same applies for jail associations. Conceptual head nod by: pjd Reviewed by: rwatson Approved by: bmilekic (mentor)
This commit is contained in:
parent
00b723c98e
commit
6661aed38d
@ -929,6 +929,10 @@ Matches all TCP or UDP packets sent by or received for a
|
||||
A
|
||||
.Ar group
|
||||
may be specified by name or number.
|
||||
.It Cm jail Ar prisonID
|
||||
Matches all TCP or UDP packets sent by or received for the
|
||||
jail whos prison ID is
|
||||
.Ar prisoniD .
|
||||
.It Cm icmptypes Ar types
|
||||
Matches ICMP packets whose ICMP type is in the list
|
||||
.Ar types .
|
||||
|
@ -204,6 +204,7 @@ enum tokens {
|
||||
|
||||
TOK_UID,
|
||||
TOK_GID,
|
||||
TOK_JAIL,
|
||||
TOK_IN,
|
||||
TOK_LIMIT,
|
||||
TOK_KEEPSTATE,
|
||||
@ -304,6 +305,7 @@ struct _s_x rule_actions[] = {
|
||||
struct _s_x rule_options[] = {
|
||||
{ "uid", TOK_UID },
|
||||
{ "gid", TOK_GID },
|
||||
{ "jail", TOK_JAIL },
|
||||
{ "in", TOK_IN },
|
||||
{ "limit", TOK_LIMIT },
|
||||
{ "keep-state", TOK_KEEPSTATE },
|
||||
@ -1284,6 +1286,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
|
||||
}
|
||||
break;
|
||||
|
||||
case O_JAIL:
|
||||
printf(" jail %d", cmd32->d[0]);
|
||||
break;
|
||||
|
||||
case O_VERREVPATH:
|
||||
printf(" verrevpath");
|
||||
break;
|
||||
@ -3298,6 +3304,22 @@ add(int ac, char *av[])
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_JAIL:
|
||||
NEED1("jail requires argument");
|
||||
{
|
||||
char *end;
|
||||
int jid;
|
||||
|
||||
cmd->opcode = O_JAIL;
|
||||
jid = (int)strtol(*av, &end, 0);
|
||||
if (jid < 0 || *end != '\0')
|
||||
errx(EX_DATAERR, "jail requires prison ID");
|
||||
cmd32->d[0] = (unsigned int)jid;
|
||||
cmd->len = F_INSN_SIZE(ipfw_insn_u32);
|
||||
ac--; av++;
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_ESTAB:
|
||||
fill_cmd(cmd, O_ESTAB, 0, 0);
|
||||
break;
|
||||
|
@ -44,7 +44,10 @@
|
||||
* 64-bit architectures, so the must be handled with care.
|
||||
*
|
||||
* "enum ipfw_opcodes" are the opcodes supported. We can have up
|
||||
* to 256 different opcodes.
|
||||
* to 256 different opcodes. When adding new opcodes, they should
|
||||
* be appended to the end of the opcode list before O_LAST_OPCODE,
|
||||
* this will prevent the ABI from being broken, otherwise users
|
||||
* will have to recompile ipfw(8) when they update the kernel.
|
||||
*/
|
||||
|
||||
enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
@ -129,6 +132,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
|
||||
O_IPSEC, /* has ipsec history */
|
||||
O_IP_SRC_LOOKUP, /* arg1=table number, u32=value */
|
||||
O_IP_DST_LOOKUP, /* arg1=table number, u32=value */
|
||||
O_JAIL, /* u32 = id */
|
||||
|
||||
O_LAST_OPCODE /* not an opcode! */
|
||||
};
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
@ -111,6 +112,7 @@ struct ip_fw_ugid {
|
||||
gid_t fw_groups[NGROUPS];
|
||||
int fw_ngroups;
|
||||
uid_t fw_uid;
|
||||
int fw_prid;
|
||||
};
|
||||
|
||||
struct ip_fw_chain {
|
||||
@ -1579,6 +1581,8 @@ check_uidgid(ipfw_insn_u32 *insn,
|
||||
INP_LOCK(pcb);
|
||||
if (pcb->inp_socket != NULL) {
|
||||
cr = pcb->inp_socket->so_cred;
|
||||
ugp->fw_prid = jailed(cr) ?
|
||||
cr->cr_prison->pr_id : -1;
|
||||
ugp->fw_uid = cr->cr_uid;
|
||||
ugp->fw_ngroups = cr->cr_ngroups;
|
||||
bcopy(cr->cr_groups, ugp->fw_groups,
|
||||
@ -1601,13 +1605,15 @@ check_uidgid(ipfw_insn_u32 *insn,
|
||||
}
|
||||
if (insn->o.opcode == O_UID)
|
||||
match = (ugp->fw_uid == (uid_t)insn->d[0]);
|
||||
else if (insn->o.opcode == O_GID)
|
||||
else if (insn->o.opcode == O_GID) {
|
||||
for (gp = ugp->fw_groups;
|
||||
gp < &ugp->fw_groups[ugp->fw_ngroups]; gp++)
|
||||
if (*gp == (gid_t)insn->d[0]) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
} else if (insn->o.opcode == O_JAIL)
|
||||
match = (ugp->fw_prid == (int)insn->d[0]);
|
||||
return match;
|
||||
}
|
||||
|
||||
@ -1921,6 +1927,7 @@ ipfw_chk(struct ip_fw_args *args)
|
||||
|
||||
case O_GID:
|
||||
case O_UID:
|
||||
case O_JAIL:
|
||||
/*
|
||||
* We only check offset == 0 && proto != 0,
|
||||
* as this ensures that we have an IPv4
|
||||
@ -2862,6 +2869,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
|
||||
|
||||
case O_UID:
|
||||
case O_GID:
|
||||
case O_JAIL:
|
||||
case O_IP_SRC:
|
||||
case O_IP_DST:
|
||||
case O_TCPSEQ:
|
||||
|
Loading…
Reference in New Issue
Block a user