ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬을 이용한 공유기(아이피타임) 원격접속
    Python 2018. 4. 24. 04:48
    SMALL

     

     

    은행 OTP 카드와 같이 와이파이도 일회용 패스워드를 발급할수는 없을까? 

     

    고민 하던 끝에 여러가지 순서를 생각했다.

     

    1. 공유기 접속 ( SSH or DDNS or webdriver 사용)

    2. turn off 되어있는 와이파이 turn on 

    3. 일회용 패스워드 랜덤 제작 후 적용 

    4. 다른 패스워드 랜덤 제작 후 적용

    5. 와이파이 turn off 

     

     

     

     

    처음에는 webdriver 모듈을 사용하려고 했는데. 나중에 Django 에 적용하여, 웹에서도 손쉽게 끄고 켜고 패스워드 변경까지하게 하려면 

    requests로 동작하게 끔 하는것이 더 괜찮겠다는 생각이 들어 새로 작성했다 .

     

    아이피타임으로 테스트를 하였으며, 먼저 DDNS 를 작동시켜보자. 구글에 검색하게 되면 많은 자료가 있으니 손쉽게 가능하다. 

     

     

    import requests
    
    class Check:
    
        def get_headers(self,session):
            headers = session.request.headers
            if headers['User-Agent']:
                headers['User-Agent'] = 'Mozilla/5.0'
            return headers
    
        def set_login_info(self, username, password):
            payload = {'username': username, 'passwd': password }
            self.login_info = payload
            print("Created..\n --self.login_info : {} \n".format(self.login_info))
        def __init__(self, url, remote_port):
    
            print('Starting DDNS status check...')
    
            try:
                check_session = requests.get('http://' + url + ':{}'.format(remote_port))
                if check_session.status_code == 200:
                    print('Router DDNS is opened.')
                    self.basic_url = url
                    self.remote_port = remote_port
                    self.headers = self.get_headers(check_session)
                    print("Created..\n --self.basic_url : {} \n --self.remote_port : {} \n --self.headers : {}\n"
                    .format(self.basic_url,self.remote_port,self.headers))
                    check_session.close()
    
            except:
                print("Couldn't connet to Router DDNS, Make sure your router is turned on")
                print("Connection Information\n -- DDNS : '{}' \n -- Remote Port : '{}'".format(url, remote_port))
    
    class Login:
    
        def __init__(self, url, remote_port, login_info, headers):
            login_url = 'http://' + url +':'+remote_port + '/sess-bin/login_handler.cgi'
    
            print('Trying to log in to DDNS...')
            session = requests.post(login_url,login_info,headers)
            self.session = session
            if 'nsetCookie' in str(session.content):
                print('Log in successfully')
                session = str(session.content)
                if 'nsetCookie' in session:
                    result = session.find('nsetCookie')
                    cookie = {'efm_session_id': session[result + 13:result + 13 + 16]}
                    self.cookie = cookie
                    print("Created..\n --self.cookie : {} \n --self.session\n".format(
                        self.cookie,self.session))
    
            elif 'session_timeout' in str(session.content):
                print('Failed to log in to DDNS, Make sure your auth information')
                print("Log in Information\n -- ID : '{}' \n -- PW : '{}'".format(login_info['username'],
                login_info['passwd']))
            else:
                print('An unknown error occurred while logging into DDNS')
    

     

    url = 'DDNS 주소 '
    port = 공유기에서 설정한, 원격 포트
    
    ddns = Check(url,remote_port)
    
    

    먼저 class Check 를 사용하여, DDNS 작동여부를 확인하고 작동이 확인되면, 해당 페이지 headers를 얻는다. 

     

    아래는 정확하게 DDNS url 과 remote_port 를 넣었을때, 접속에 성공된 모습이다. 

    헤더에 user-agent 는 원래 python으로 기록되는데. Check.get_headers 함수에서 mozilla로 변환하여 반환하였다. 

     

     

    아래는 접속에 실패하였다. 접속 실패 시 사용자가 입력한 값을 반환하여 보여준다.

     

     

     

     

     

    정상적으로 접속됨을 확인하면 , 아래 함수를 실행하여 공유기 관리자 아이디와 패스워드를 입력하자

     

    ddns.set_login_info('che','22222')
    

     

    아래는 단순하게 ddns 객체에 .login_info에 dictionary 형식으로 관리자 로그인 정보가 기록된다. 

     

     

     

     

    이제 로그인에 필요한 모든 정보를 갖추었다. 로그인은 class Login 으로 가능하고 , 위 ddns 객체가 가지고있는 정보를 사용하면, 간단하게 로그인 세션 쿠키까지 저장된다. 

     

    * 세션쿠키는 따로 저장을 무조건 해야하는 이유가 로그인만 하고나서는 쿠키없이 아무것도 할수없다. 예를들면 , 다른 페이지로 이동하던지 , 공유기를 끄고 켜고 패스워드를 변경하고 업데이트를 실시하는등 모든 작업은 로그인 세션쿠키가 필요하다 

     

     

     

     

    connect = Login(ddns.basic_url,ddns.remote_port,ddns.login_info,ddns.headers)

    위와 같이 처음 class Check로 생성한 정보들을 사용하여 class Login을 사용하고 , 접속한다. 접속에 성공하면 아래와같이 , 세션 쿠키를 dictionary형태로 획득할수있다.

     

    * 쿠키는 얻는 방법이 여러가지 있지만, 몇번 돌려보니 쿠키 length가 일정하길래 그냥 str로 변환하여 잘라서 입력하였다.  requests 기능에도 쿠키를 얻는 메소드가 있는걸로 알고있다. 

     

     

     

     

    접속 실패 시, 입력한 로그인 정보를 반환하여 보여준다.

     

     

     

    감사합니다.

     

     

    BIG

    댓글

Designed by Tistory.