python-iptables icon indicating copy to clipboard operation
python-iptables copied to clipboard

conflict with docker(swarm).

Open crazy-canux opened this issue 5 years ago • 6 comments

when i update iptables after use docker swarm deploy some stack. It's failed. Anybody knows how to fix this?

Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/applianced/job_base.py", line 73, in run
self._run_impl()
File "/usr/local/lib/python3.5/dist-packages/applianced/firewall.py", line 30, in _run_impl
init_filter()
File "/usr/local/lib/python3.5/dist-packages/applianced/firewall.py", line 61, in init_filter
it.clean_user_define_chain()
File "/usr/local/lib/python3.5/dist-packages/applianced/iptables_wrapper.py", line 48, in clean_user_define_chain
self.table.commit()
File "/usr/local/lib/python3.5/dist-packages/iptc/ip4tc.py", line 1598, in commit
raise IPTCError("can't commit: %s" % (self.strerror()))
iptc.ip4tc.IPTCError: can't commit: b'Resource temporarily unavailable'

crazy-canux avatar Nov 27 '19 10:11 crazy-canux

Can you share the code triggering this exception?

Also, does this run in a Docker container?

ldx avatar Nov 27 '19 19:11 ldx

  1. docker swarm init
  2. docker deploy ... (start some stack)
  3. modify iptables like:
        try:
            logger.debug("delete all rules from chain.")
            self.table.autocommit = False
            for chain in self.table.chains:
                for rule in chain.rules:
                    chain.delete_rule(rule)
            self.table.commit()
            self.table.refresh()
            self.table.autocommit = True
        except Exception:
            raise

the code running on host not container.

crazy-canux avatar Nov 28 '19 02:11 crazy-canux

Does this package support "iptables -w"? maybe wait can fix this.

crazy-canux avatar Nov 28 '19 02:11 crazy-canux

   -w, --wait [seconds]
          Wait  for  the  xtables  lock.   To prevent multiple instances of the program from running concurrently, an
          attempt will be made to obtain an exclusive lock at launch.  By default, the program will exit if the  lock
          cannot  be  obtained.   This option will make the program wait (indefinitely or for optional seconds) until
          the exclusive lock can be obtained.

crazy-canux avatar Nov 28 '19 02:11 crazy-canux

No, python-iptables does not use the lockfile. It should be pretty easy to add locking, though. This is how it's done in the iptables command line tool:

bool xtables_lock(int wait, struct timeval *wait_interval)
{
	struct timeval time_left, wait_time, waited_time;
	int fd, i = 0;

	time_left.tv_sec = wait;
	time_left.tv_usec = 0;
	waited_time.tv_sec = 0;
	waited_time.tv_usec = 0;

	fd = open(XT_LOCK_NAME, O_CREAT, 0600);
	if (fd < 0)
		return true;

	while (1) {
		if (flock(fd, LOCK_EX | LOCK_NB) == 0)
			return true;
		if (++i % 10 == 0) {
			if (wait != -1)
				fprintf(stderr, "Another app is currently holding the xtables lock; "
					"still %lds %ldus time ahead to have a chance to grab the lock...\n",
					time_left.tv_sec, time_left.tv_usec);
			else
				fprintf(stderr, "Another app is currently holding the xtables lock; "
						"waiting for it to exit...\n");
		}

		wait_time = *wait_interval;
		select(0, NULL, NULL, NULL, &wait_time);
		if (wait == -1)
			continue;

		timeradd(&waited_time, wait_interval, &waited_time);
		timersub(&time_left, wait_interval, &time_left);
		if (!timerisset(&time_left))
			return false;
	}
}

ldx avatar Dec 02 '19 17:12 ldx

This might not be relevant anymore, but doesn't this work?

self.table.refresh()
for chain in self.table.chains:
    chain.flush()

jllorente avatar Jan 31 '21 02:01 jllorente