Shutdown Interface with BASH/Command Line



  • Hello,

    I've been experiencing tcp outages on my pfsense more likely than not caused by my ISP shutting down my connection. Other protocols (including ping and udp) work just fine. What I found to do the trick in fixing my issue is power-cycling my WAN interface. The problem is, I'm not always around to do it manually. I created this python script to run with cron on a regular basis as a patch fix to my issue.

    0_1530341475593_9badb134-d5bc-4e32-9881-1a1e5ddff18c-image.png

    Now this works just fine with other *nux environments but with pfSense, well it runs into problems with pfSense. The freeBSD backbone of pfSense accepts the shutdown of em0(my WAN) just fine but pfSense keeps on trucking on not noticing the change. Where can I find the config file/program/anything to turn off a specific interface in pfSense via bash?

    Any help is appreciated and if you have a coding critiques, I'd love to hear them

    Sincerely,
    1nfra


  • Netgate Administrator

    So you're saying manually running ifconfig em0 down does not bring down the WAN?

    What connection type is your WAN?

    You might try instead:
    /etc/rc.linkup stop wan
    /etc/rc.linkup start wan

    Steve



  • Thanks Stephen for the reply.

    In freeBSD, the connection is severed, and therefore there is no WAN interface connection in pfSense. BUT, the interface presents itself differently depending on how it was shut down.

    I've attached screenshots of disabling the WAN address via pfSense GUI, "ifconfig em0 down", and "/etc/rc.linkup stop wan":

    0_1530378054575_66dfba51-098c-4e14-94a5-b182cf21f363-image.png via pfSense GUI

    .

    0_1530378219868_3dfe0d03-e6bd-4556-88eb-ee89d8680ca0-image.png ifconfig em0 down

    .

    0_1530377809036_e030dccb-ce68-4dd5-bea5-f54c27b0ecbd-image.png /etc/rc.linkup stop wan

    I'm not sure if it matters how the device was taken down, but I did think it was important to note. I will probably be doing "ifconfig em0 down" paired with "ip address flush em0" and "/etc/rc.linkup stop wan" just to cover my bases.


  • Netgate Administrator

    Let us know how it goes. I wouldn't expect to have to do everything there though.

    Obviously I wouldn't expect to have to do it at all! But that's another matter. 😉

    Steve



  • Update:

    I updated my program to be a little more robust to included reverse dns lookups to allow dynamic IP changes. I've ran into some issues with permissions and have been trying to figure out a workaround.

    """
    Created by 1nfra for open source use
    6/30/2018
    
    This script will check for an external connection via http port 80 to large coporation websites
    If connections fails 5 times, program will restart wan interface (you will need to change the
    interface variable within the program to match that of the pfSense)
    
    Logging is created and inserted into interfaceAutoRestart.log as the same folder as the script
    
    """
    
    import socket
    import time
    import os
    from datetime import datetime
    import sys
    
    interface = "em0"
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    count = 0
    
    #All sites that will be tried to connect to
    sites = {1:"www.google.com", 2:"www.yahoo.com", \
      3:"www.bing.com", 4:"www.cnn.com", 5:"www.facebook.com", \
      6:"www.google.com", 7:"www.youtube.com", 8:"www.amazon.com", \
      9:"www.ebay.com", 10:"www.microsoft.com"}
    
    #10 attempts with 5 restarts before program exits automatically
    while count < 10:
      
      #intializes variabel result before try block
      result = 1
      
      
      #Try to get IP from reversdns lookup, use IP and check for socket connection to port 80 of IP
      try:
        #Gets IP via DNS from sites[count + 1]
        sitecheck = socket.gethostbyname(sites[count + 1])
        result    = sock.connect_ex((sitecheck,80))
      except:
        print ("error found in executing dns lookup or socket connect")
        
    	
      #if socket connection is successful, leave while loop
      if result == 0:
        break
    
      #5 attempts over a 5 minute interval before executing restart attempt
      elif count < 5:
        time.sleep(30)
    
      #After 5 failed socket attemtps, program writes to log and power cyles the interface
      elif count >= 5:
        #sets datetime variable for logging purposes
        dateTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        #Opens, writes, and closes logging
        log = open("interfaceAutoRestart.log", "a+")
        log.write(dateTime + "  Ping test failed: Running auto restart of " + interface + "\n")
        log.close()
    
        #executes bash commands to restart wan over a period of 90 seconds
        os.system("/etc/rc.linkup stop wan")
        time.sleep(90)
        os.system("/etc/rc linkup start wan")
        #allows the interface time to figure it stuff out
        time.sleep(30)
    
      #counts up unless broken from success socket connect on port 80	
      count += 1
    
    #exits the program
    print("Exit")
    sys.exit()
    exit()
    

    Issue #1: Running /etc/rc.linkup stop(start) wan with enough permissions
    When I run this item as root, I am given "sh: /etc/rc: Permission denied". I have tried running it through with sticky bits as well as chmod 777 just to see if the issue if fixed

    Issue #2: crontab does not want to accept the level of permission I would like to grant it. The script will not run through crontab saying "/bin/sh: /root/wanAutoRestart.py: Permission denied". I am running it in the crontab of root

    0_1530914038698_296153b0-705f-41bd-8cbc-0b1db99c4cef-image.png

    0_1530914048731_e2d1a778-55a8-45fe-88ab-8ff005cd0821-image.png

    Issue#3: When the original issue occurs (TCP connections will not create sessions) and I powercycle the WAN interface with /etc/rc linkup commands manually, I will have Internet for about a minute before the interface shuts down again. I do know why this happens.

    P.S. I was trying to run the python script with the runWanAutoRestart.sh to see if this would fix the permissions error with crontab. It did not work, so please ignore it.