Here's how I thought this could work:

  1. vpn connection goes down
  2. NetworkManager then runs through dispatcher scripts on a connection change, sees the vpn-down action.
  3. script sees the vpn-down action and sets iptables to block all traffic
  4. I select vpn connection using NetworkManager applet
  5. NetworkManager runs through dispatcher scripts on a connection change, sees the pre-up action.
  6. script sees the pre-up action and sets iptables to allow traffic again
  7. now that iptables is restored to allow traffic, vpn connection is established.

But things break down at step 5. Instead of running the script that is in the /etc/NetworkManager/dispatcher.d/pre-up.d directory, NetworkManager just turns and turns until I get a Network Connection Failed notification (since the iptables rules are changed to block everything at step 3-- see below for specific rules). Indeed, it doesn't appear as if the script in pre-up.d is even being run (I have it logging the arguments it receives to a file in /tmp but nothing gets logged.)

So my questions are, why does iptables block the dispatcher scripts from running at all (or in other words why won't NetworkManager run these scripts when iptables is set to block everything except lo), and how could I configure iptables to block all traffic but also allow the NetworkManager enough leeway to run the pre-up dispatcher scripts (such that on trying to reconnect to the vpn, the dispatcher can restore the permissive iptables rules)?

(note: The script in step 3 sets iptables to:

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP


edit: here's all the script in pre-up.d does. It is stripped down because i was trying to see if it was even being run (it's not). all I wanted it to do was spit out the arguments it got to a log, but I'm getting nothing when iptables is restrictive:

#!/usr/bin/env python3

import sys
import logging
from time import gmtime, strftime

logging.basicConfig(filename='/tmp/10test.log', filemode='a', level=logging.DEBUG)
logger = logging.getLogger(name)

iface = sys.argv[1]
action = sys.argv[2]

now = strftime('%Y-%m-%d %H:%M:%S', gmtime())

logging.info(f'time is {now}')
logging.info(f'interface is {iface}')
logging.info(f'action is {action}')

edit2: Here is the script that does execute successfully in step #3. Note that both scripts have the same permissions:

#!/usr/bin/env python3

import sys
import subprocess
import logging
import os

logging.basicConfig(filename='/tmp/pypia.log', filemode='a', level=logging.DEBUG)
logger = logging.getLogger(__name__)

config_dir = '/etc/pypia'
if not os.path.isdir(config_dir):
    logging.debug('making pypia config directory in /etc')

action = sys.argv[2]
logging.debug(f'action is {action}')

if not os.path.isfile('/tmp/pia_ks_status.conf'):
    logging.info('kill switch status file not found. exiting.')

with open('/tmp/pia_ks_status.conf', 'r') as f:
    logging.debug('loading kill switch status file from /tmp')
    status = f.readline().strip()
    logging.info(f'status is {status}')

if (status == 'active') and (action == 'vpn-down'):
    logging.debug('writing iptables backup file...')
    with open(os.path.join(config_dir, 'iptables.bak'), 'w') as f:
        subprocess.call(['iptables-save'], stdout=f)
    logging.debug('using nmcli to shut off all connected devices...')
    subprocess.call(['iptables', '-A', 'INPUT', '-i', 'lo', '-j', 'ACCEPT'])
    subprocess.call(['iptables', '-A', 'OUTPUT', '-o', 'lo', '-j', 'ACCEPT'])
    subprocess.call(['iptables', '-P', 'INPUT', 'DROP'])
    subprocess.call(['iptables', '-P', 'OUTPUT', 'DROP'])
    subprocess.call(['iptables', '-P', 'FORWARD', 'DROP'])
  • iptables isn't blocking the scripts. It doesn't have that capacity, especially if the vpn-down script works. I'd look at a problem with Network Manager and it not running the script moreso than pointing blame at iptables – Thomas Ward Jul 16 '18 at 18:43
  • Could very well be some issue with NetworkManager rather than iptables-- didn't mean to cast aspersions :-). When iptables is set to accept all (e.g. -P INPUT ACCEPT, etc), both the down and up dispatcher scripts run. It's only when I activate the restrictive iptables rules that the script in pre-up.d fails to run. So it seemed logical that something with my iptables configuration was the issue. – dagrha Jul 16 '18 at 18:53
  • It'd help if we knew the scripts being run - my guess is something is not behaving, but without seeing what your script is attempting it'll be impossible to debug/diagnose – Thomas Ward Jul 16 '18 at 19:10
  • so it sounds to me like it just doesn't know how to execute the scripts, or it can't execute custom python scripts or such. If it's not doing anything here, though, it sounds like there's a bigger issue at hand. Your script does what it is supposed to when you run it directly, yes? – Thomas Ward Jul 16 '18 at 19:57
  • Yes, the script does what it is supposed to if I run it directly. NetworkManager dispatcher doesn't have a problem with the "custom python script" I wrote for the vpn-down condition-- i'll add that script to my post as well. In other words, it is having issues only when the restrictive iptables rules are in place – dagrha Jul 16 '18 at 20:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.