2017-02-23 93 views
0

编程仍然是新的,我试图创建一个脚本,检测端口在远程主机上不可用,并更改iptables发送一个单一的通知。尝试&除了在一个while循环

我运行Ubuntu 16.04中,我使用Python3,我使用os模块发送电子邮件&变化的IPtables

我几乎可以得到但它的工作,试图只有一次得到它的电子邮件是证明challange。

import socket 
import sys 
import time 
import datetime 
import os 
import logging 

#Variables 
remote_host = "syslog1" 
drop = os.system("iptables-restore < iptables.conf") 
undrop = os.system("iptables-restore < DR-iptables.conf") 
print ('Starting Syslog DR Plan.') 

# run continuously 

while True: 
    time.sleep(1) 
    for remote_port in [514]: 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.settimeout(60) 
     now = datetime.datetime.now() 
     now_text = now.strftime("%Y-%m-%d %H:%M:%S") 
     plco = 0 

     try: 
      sock.connect((remote_host, remote_port)) 
      print((now_text, 'Port is Open on', remote_port)) 


     except: 
      socket.timeout 
      plco = 1 

    if plco == 1: 
     undrop 
     logging.basicConfig(filename='/var/log/syslog',level=logging.DEBUG , format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') 
     logging.error('#### Syslog DR Invoked - Immediate action required ####') 
     os.system("mail -s '# INVESTIGATE IMMEDIATELY - SYSLOG1 port 514 unreachable #' [email protected] < ./panic.txt") 
     print('Port is closed') 

    else: 
     pass 
sock.close() 

我怀疑我需要做两件事之一,但迄今为止失败。一个是将其定义为一个函数,然后调用该函数,然后根据输出设置另一个函数来发送电子邮件。

任何人都可以建议去哪里,或者更好的方法来做到这一点(我可能会做的事情是硬/错的方式)。

非常感谢

+0

你的'except'块捕获任何和所有的异常 - 你应该改变它'除了socket.timeout:';这样,任何意外的行为仍会引发异常(例如键盘中断) – nlsdfnbch

+0

另外,请确保您发布可执行代码;你有一些拼写错误。 – nlsdfnbch

+0

谢谢你的建议。我会再看一眼,让你知道我是怎么回事。 – user617932

回答

0

你想发送每当这是试图连接到端口的套接字超时电子邮件的代码。这可以通过使用你的代码来实现:

import socket 
import sys 
import time 
import datetime 
import os 
import logging 

logging.basicConfig(filename='/var/log/syslog', level=logging.DEBUG, 
        format='%(asctime)s %(message)s', 
        datefmt='%m/%d/%Y %I:%M:%S %p') 

log = logging.getLogger(__name__) 

escalated = False 
while True: 
    time.sleep(1) 
    for remote_port in [514]: 
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     sock.settimeout(60) 
     now = datetime.datetime.now() 
     now_text = now.strftime("%Y-%m-%d %H:%M:%S") 


     try: 
      sock.connect((remote_host, remote_port)) 
      print((now_text, 'Port is Open on', remote_port)) 
      escalated = False 


     except (socket.timeout, ConnectionRefusedError): 
      if not escalated: 
       log.error('#### Syslog DR Invoked - Immediate action required ####') 
       os.system("mail -s '# INVESTIGATE IMMEDIATELY - SYSLOG1 port 514 " 
         "unreachable #' [email protected] < ./panic.txt") 
       escalated = True 
      print('Port is closed') 

    sock.close() 
+0

非常感谢,理想情况下,我希望让脚本继续运行,以便在服务器恢复联机后不必重新启动脚本。现在,我会增加时间。感谢您的帮助:) – user617932

+0

我添加了一个检查 - 它现在只会通知您,如果它以前工作 - 这意味着您将只收到一封邮件,直到端口再次打开。如果这解决了您的问题,请考虑将答案标记为已接受。 – nlsdfnbch

+0

如果你想跟踪你正在使用的'for'循环提示的多个端口,你必须跟踪'dict'中的'escalated'值,而不是简单的bool。否则它将无法正常工作。 – nlsdfnbch