core: firewall integration with DynamicUserNFTSet=
New directive `DynamicUserNFTSet=` provides a method for integrating
configuration of dynamic users into firewall rules with NFT sets.
Example:
```
table inet filter {
set u {
typeof meta skuid
}
chain service_output {
meta skuid != @u drop
accept
}
}
```
```
/etc/systemd/system/dunft.service
[Service]
DynamicUser=yes
DynamicUserNFTSet=inet:filter:u
ExecStart=/bin/sleep 1000
[Install]
WantedBy=multi-user.target
```
```
$ sudo nft list set inet filter u
table inet filter {
set u {
typeof meta skuid
elements = { 64864 }
}
}
$ ps -n --format user,group,pid,command -p `pgrep sleep`
USER GROUP PID COMMAND
64864 64864 55158 /bin/sleep 1000
```
This commit is contained in:
committed by
Topi Miettinen
parent
c0548df0a2
commit
46c3b1ff88
@@ -4083,6 +4083,43 @@ static int add_shifted_fd(int *fds, size_t fds_size, size_t *n_fds, int fd, int
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void exec_op_dynamic_user_nft_set(bool add, const ExecContext *c, uid_t uid) {
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
for (size_t i = 0; i < c->n_dynamic_user_nft_set_contexts; i++) {
|
||||
NFTSetContext *s = &c->dynamic_user_nft_set_context[i];
|
||||
if (add)
|
||||
r = nft_set_element_add_uint32(s, uid);
|
||||
else
|
||||
r = nft_set_element_del_uint32(s, uid);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "%s NFT family %s table %s set %s UID " UID_FMT " failed, ignoring: %m",
|
||||
add? "Adding" : "Deleting", nfproto_to_string(s->nfproto), s->table, s->set, uid);
|
||||
}
|
||||
}
|
||||
|
||||
static void exec_add_dynamic_user_nft_set(const ExecContext *c, uid_t uid) {
|
||||
exec_op_dynamic_user_nft_set(true, c, uid);
|
||||
}
|
||||
|
||||
void exec_delete_dynamic_user_nft_set(const ExecContext *c, DynamicUser *d) {
|
||||
int r;
|
||||
uid_t uid;
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
r = dynamic_user_current(d, &uid);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Can't get current dynamic user, ignoring: %m");
|
||||
return;
|
||||
}
|
||||
|
||||
exec_op_dynamic_user_nft_set(false, c, uid);
|
||||
}
|
||||
|
||||
static int exec_child(
|
||||
Unit *unit,
|
||||
const ExecCommand *command,
|
||||
@@ -4284,6 +4321,8 @@ static int exec_child(
|
||||
if (dcreds->user)
|
||||
username = dcreds->user->name;
|
||||
|
||||
exec_add_dynamic_user_nft_set(context, uid);
|
||||
|
||||
} else {
|
||||
r = get_fixed_user(context, &username, &uid, &gid, &home, &shell);
|
||||
if (r < 0) {
|
||||
@@ -5346,6 +5385,8 @@ void exec_context_done(ExecContext *c) {
|
||||
c->user = mfree(c->user);
|
||||
c->group = mfree(c->group);
|
||||
|
||||
c->dynamic_user_nft_set_context = nft_set_context_free_many(c->dynamic_user_nft_set_context, &c->n_dynamic_user_nft_set_contexts);
|
||||
|
||||
c->supplementary_groups = strv_free(c->supplementary_groups);
|
||||
|
||||
c->pam_name = mfree(c->pam_name);
|
||||
@@ -6020,6 +6061,11 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||
fprintf(f, "%sGroup: %s\n", prefix, c->group);
|
||||
|
||||
fprintf(f, "%sDynamicUser: %s\n", prefix, yes_no(c->dynamic_user));
|
||||
for (size_t i = 0; i < c->n_dynamic_user_nft_set_contexts; i++)
|
||||
fprintf(f, "%sDynamicUserNFTSet: %s:%s:%s\n", prefix,
|
||||
nfproto_to_string(c->dynamic_user_nft_set_context[i].nfproto),
|
||||
c->dynamic_user_nft_set_context[i].table,
|
||||
c->dynamic_user_nft_set_context[i].set);
|
||||
|
||||
strv_dump(f, prefix, "SupplementaryGroups", c->supplementary_groups);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user