1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Script: Change WPA key automatically every week...

Discussion in 'Tomato Firmware' started by philess, Apr 24, 2013.

  1. philess

    philess Networkin' Nut Member

    Hey guys, just thought i would share this very simple script.
    Maybe someone can find it useful.

    The purpose of it is that it is run at a custom interval (scheduler: every monday etc),
    changes the WPA key of your (guest-)network to a new randomly generated one
    and sends you an email about it. I am using this for a client who requested this.

    # /opt/tomato/changewpa.sh
    # change wl0.1 to whatever wireless interface you want to use
    old_wpakey=`nvram get wl0.1_wpa_psk`
    ssid=`nvram get wl0.1_ssid`
    # from what characters/numbers should the new key be chosen from
    # (i like to keep it easy to read when printed out, so no oO and iI etc)
    # Length of the new key (NOTE: minium is 8 for WPA2)
    echo "Old password for $ssid is: $old_wpakey"
    # generate new random key
    NEWKEY=`cat /dev/urandom | tr -dc $CHARS | head -c$LENGTH`
    echo "New password has been generated: $NEWKEY"
    echo "Stopping NAS service..."
    service nas stop
    echo "Saving new password..."
    nvram set wl0.1_wpa_psk="$NEWKEY"
    nvram commit
    echo "Starting NAS service..."
    service nas start
    # get current (new) password
    current_wpakey=`nvram get wl0.1_wpa_psk`
    echo "New password for $ssid is: $current_wpakey"
    # send email with current config
    echo "Sending email..."
    python /opt/tomato/mail/wpakeyemail.py "$ssid" "$old_wpakey" "$current_wpakey" /dev/null 2>&1
    # at this point you can easily remove the above email line/add your own type of messaging
    # write to log
    logger -p INFO -t CHANGEWPA "WLAN password for network $ssid has been changed."

    Now the email part (needs python installed)

    import datetime
    import os
    import mail
    import sys
    time = datetime.datetime.now()
    formatted_time = time.strftime("%A, %d. %B %Y %H:%M:%S")
    recipient = "your_recipient@email.com"
    ssid = sys.argv[1]
    oldpassword = sys.argv[2]
    newpassword = sys.argv[3]
    subject = "[PASSWORD] New WLAN password"
    message = A new password for the network '" + ssid + "' has been generated and is active.\r\n\r\n\r\n\r\n\r\n\r\nNew password: " + newpassword + "\r\n\r\n\r\n\r\n\r\n\r\nThe previous password was: " + oldpassword + "\r\n\r\n" + formatted_time + "\r\n\r\nEOF"
    mail.sendMail(recipient, subject, message)
    import os
    import smtplib
    import mimetypes
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEBase import MIMEBase
    from email.MIMEText import MIMEText
    from email.MIMEAudio import MIMEAudio
    from email.MIMEImage import MIMEImage
    from email.Encoders import encode_base64
    def sendMail(recipient, subject, text, *attachmentFilePaths):
      gmailUser = 'youremail@gmail.com'
      gmailPassword = 'aaaaaaaaaaaaa'
      msg = MIMEMultipart()
      msg['From'] = gmailUser
      msg['To'] = recipient
      msg['Subject'] = subject
      for attachmentFilePath in attachmentFilePaths:
      mailServer = smtplib.SMTP('smtp.gmail.com', 587)
      mailServer.login(gmailUser, gmailPassword)
      mailServer.sendmail(gmailUser, recipient, msg.as_string())
      print('Sent email to %s' % recipient)
    def getAttachment(attachmentFilePath):
      contentType, encoding = mimetypes.guess_type(attachmentFilePath)
      if contentType is None or encoding is not None:
        contentType = 'application/octet-stream'
      mainType, subType = contentType.split('/', 1)
      file = open(attachmentFilePath, 'rb')
      if mainType == 'text':
        attachment = MIMEText(file.read())
      elif mainType == 'message':
        attachment = email.message_from_file(file)
      elif mainType == 'image':
        attachment = MIMEImage(file.read(),_subType=subType)
      elif mainType == 'audio':
        attachment = MIMEAudio(file.read(),_subType=subType)
        attachment = MIMEBase(mainType, subType)
      attachment.add_header('Content-Disposition', 'attachment',  filename=os.path.basename(attachmentFilePath))
      return attachment
    Now you can use the scheduler to run '/opt/tomato/changewpa.sh' at custom times, or run it manually.

    The email output will look like this then:
    Subject: [PASSWORD] New WLAN password
    A new password for the network 'Tomato' has been generated and is active.
    New password: 3Wty9tpd
    The previous password was: 8CXwH6d4
    Sunday, 21. April 2013 22:31:33
    It should be very simple to costumize the layout etc.

    Please note: I tested this using Tomato 1.28.9013.Victek, the way the wl driver is
    restarted *could* be different for other mods, but i doubt it.

    Installing pything, please look at other threads about Entware or Optware, it is very simple.

    Credit and huge thanks to lancethepants who posted the mail.py that i slightly modified in this thread:
    octra, mpegmaster, Victek and 3 others like this.
  2. occamsrazor

    occamsrazor Network Guru Member

    I don't need this myself, but just wanted to say that's very cool! Well done...
    mpegmaster and philess like this.
  3. FlashSWT

    FlashSWT LI Guru Member

    Very cool. Of course the first thing I thought of was this photo I've seen online: :D

  4. happyfeethax

    happyfeethax Reformed Router Member

    wow that's a pretty handy script o.o how to implement that to post on Facebook or other social media for guest networks lol
    philess likes this.
  5. philess

    philess Networkin' Nut Member

  6. srouquette

    srouquette Network Guru Member

    I wonder if it would be possible to send email with mandrill, it should be easier than installing python on the router.

    edit: well too bad, wget was built with limited option and doesn't support --post-data.
  7. philess

    philess Networkin' Nut Member

  8. srouquette

    srouquette Network Guru Member

    the problem is more about installing stuff on the router :)
    it would be nice if it could work with a simple script, out of the box.
    the openssl s_client patch would be nice :)
  9. philess

    philess Networkin' Nut Member

    Yeah i realize that. But i have no clue how it would be possible just with Busybox.
  10. jerrm

    jerrm Network Guru Member

    Post a "me too" response to the patch thread. Give it a little more visibility and let the developers know it would be useful to a broader user base. I didn't know if I was alone in my desire or not.

    Shibby was at least looking at it, no clue if it made the cut for 109 or not.

Share This Page