Можно ли использовать iptables, чтобы разрешить трафик, инициированный "процессом", т.е. используя имя процесса? Я хотел бы, например, разрешить все, что инициируется командой ping.
Создать правило iptables для процесса/службы
Ответ 1
Похоже, что модуль владельца iptables - это то, что вы хотите. Во-первых, проверьте, доступно ли это в вашей системе:
iptables -m owner --help
Вы можете прочитать больше здесь: http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#OWNERMATCH
Ответ 2
-m owner --pid-owner PID
См. http://linuxpoison.blogspot.com/2010/11/how-to-limit-network-access-by-user.html и http://linux.die.net/man/8/iptables
Обратите внимание, что вам нужен модуль ipt_owner, поскольку -pid-владелец не поддерживается xt_owner.
Например (это просто приближение)
#!/bin/bash
[email protected] &
iptables -m owner --pid-owner %1 -j REJECT
В действительности же вам лучше использовать --uid-owner и -gid-owner. Во-первых, критерий -pid-владельца соответствует только точной pid, то есть ваша программа может легко порождать дочерний процесс, который не будет блокироваться этим правилом. (По крайней мере, я не читал иначе.) Во-вторых, iptables (8) предупреждает, что -IP-владелец разбит на SMP-системах (которые могут или не могут применяться к вам, но в любом случае переносимость ограничений). В-третьих, есть условие гонки в script выше, потому что процесс запускается до его блокировки. (Если есть способ получить процесс pid до его начала, я никогда не слышал об этом.)
Ответ 3
Если есть способ получить процесс pid до его запуска, я никогда не слышал об этом.
Вы можете написать оболочку, которая сначала открывает, а затем добавляет правило и выполняет процесс (при условии, что запущенная программа не вилка), поскольку PID не изменяется вызовом exec (3).
/* NOTE this contains zero error checking */
int main(int argc, char **argv) {
/* Eat argv[0] the name of the wrapper script */
argv++;
argc--;
pid_t my_pid = getpid();
char *iptables_cmd = NULL;
asprintf(&iptables_cmd, "/sbin/iptables -A INPUT -m owner --pid_owner %d -j ACCEPT", my_pid);
system(iptables_cmd);
execv(argv[0], argv);
}