2017-02-23 90 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