Is there any damn documentation and where is it hiding?
Existem exemplos no site netfilter que ajudam a explicar a funcionalidade. Aqui está uma função que escrevi no meu próprio código que configura o netfilter NFLOG.
Aqui estão os exemplos que eles fornecem: link
void setup_netlogger_loop(
int groupnum,
queue_t queue)
{
int sz;
int fd = -1;
char buf[BUFSZ];
/* Setup handle */
struct nflog_handle *handle = NULL;
struct nflog_g_handle *group = NULL;
memset(buf, 0, sizeof(buf));
/* This opens the relevent netlink socket of the relevent type */
if ((handle = nflog_open()) == NULL){
sd_journal_perror("Could not get netlink handle");
exit(EX_OSERR);
}
/* We tell the kernel that we want ipv4 tables not ipv6 */
if (nflog_bind_pf(handle, AF_INET) < 0) {
sd_journal_perror("Could not bind netlink handle");
exit(EX_OSERR);
}
/* Setup groups, this binds to the group specified */
if ((group = nflog_bind_group(handle, groupnum)) == NULL) {
sd_journal_perror("Could not bind to group");
exit(EX_OSERR);
}
if (nflog_set_mode(group, NFULNL_COPY_PACKET, 0xffff) < 0) {
sd_journal_perror("Could not set group mode");
exit(EX_OSERR);
}
if (nflog_set_nlbufsiz(group, BUFSZ) < 0) {
sd_journal_perror("Could not set group buffer size");
exit(EX_OSERR);
}
if (nflog_set_timeout(group, 1500) < 0) {
sd_journal_perror("Could not set the group timeout");
}
/* Register the callback */
nflog_callback_register(group, &queue_push, (void *)queue);
/* Get the actual FD for the netlogger entry */
fd = nflog_fd(handle);
/* We continually read from the loop and push the contents into
nflog_handle_packet (which seperates one entry from the other),
which will eventually invoke our callback (queue_push) */
for (;;) {
sz = recv(fd, buf, BUFSZ, 0);
if (sz < 0 && errno == EINTR)
continue;
else if (sz < 0)
break;
nflog_handle_packet(handle, buf, sz);
}
}
Is the CONNMARK thing actually necessary? That is, would this work just as well?
É desnecessário.
Is it necessary to have "ulogd" running for this to work?
Não - na verdade eu não uso este aplicativo.
Is there a way to tell the kernel to pick an unallocated group number for me and tell me what it is?
Não que eu saiba. Em qualquer caso, isso seria inútil se você tivesse a configuração de destinos NFLOG para HTTP, um para registrar pacotes descartados que eram FTP e um que estava verificando sequências SMTP. Nesse cenário, você não pode determinar qual regra está vinculada a qual grupo e, portanto, qual grupo deve ser ouvido.
Is there a way to tell the kernel that these filter rules should be automatically deleted when process X terminates? (Process X would not be running as uid 1000.)
Não, mas o kernel preenche um buffer apenas até o tamanho máximo e, em seguida, descarta os dados. Não representa um impacto no desempenho em termos de usar muita memória com regras não escutadas.
Presumably the iptables command makes some special ioctl calls or something to configure the firewall. Is there a C library that can be used to do the same from within a program (namely, "process X" from Q4)?
Não há biblioteca de netfilters que eu saiba que ajude a manipular as regras. Existe uma biblioteca controlada internamente que é usada em seu lugar.
IPtables herda um método bastante arcaico de falar com userspace - você abre um soquete de IP SOCK_RAW para se comunicar com ele. Isso será totalmente removido (como não faz sentido) com nftables que falarão sobre o netlink para fazer a mesma coisa.