2011-06-12 5 views
3

예전에 나는 네트워크에서 컴퓨터를 켜기 위해 작은 WOL 스크립트를 [Google의 도움을 받아] 작성했습니다. 스크립트는 다음과 같습니다.WOL from outside WAN

exec /usr/bin/python -x "$0" "[email protected]" 
# 
node_lst = [ 
     'srv1 0a:1b:8c:0d:2e:7f', 
     'srv2 0A-0B-4C-8D-CE:3F', 
] 
# 
import os,sys,string,commands 
import struct, socket 
import re,random 

retval = 0 

mac_addr = "mac_addr.txt" 
X = '([a-zA-Z0-9]{2}[:|\-|.]?){5}[a-zA-Z0-9]{2}' 
S = re.compile(r'\s+') 

mmap = {} 

## First argument 'None' in str.translate is new in 2.6. 
## Previously, it was a string of 256 characters 
if sys.version_info < (2, 6): 
    f1_arg = ''.join(chr(i) for i in xrange(256)) 
else: 
    f1_arg = None 

## broadcast address 
sysOS = "uname -s" 
BSD = "ifconfig | grep -w broadcast | cut -d\ -f 6" 
LNX = "ip -o addr show | grep -w inet | grep -e eth | cut -d\ -f 9" 
# 
if commands.getoutput(sysOS) == "Linux": 
    bCast = commands.getoutput(LNX) 
elif commands.getoutput(sysOS) == "Darwin": 
    bCast = commands.getoutput(BSD) 
else: 
    print "System not supported!!" 
    sys_exit() 

def WakeOnLan(mac_address): 

    ## Building the Wake-On-LAN "Magic Packet"... 
    ## Pad the synchronization stream. 
    data = ''.join(['FFFFFFFFFFFF', mac_address * 20]) 
    msg = '' 

    ## Split up the hex values and pack. 
    for i in range(0, len(data), 2): 
     msg = ''.join([msg, struct.pack('B', int(data[i: i + 2], 16))]) 

    ## ...and send it to the broadcast address using UDP 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
    s.sendto(msg, (bCast, 9)) 
    s.close() 

def sys_exit(): 
    sys.stdout.flush() 
    sys.exit(1) 

## check if hostname is provided 
if len(sys.argv) != 2: 
    print "Usage: %s <hostname>" % sys.argv[0] 
    sys_exit() 

for i in node_lst: 
    # strip off everything from first "#" [if] found 
    i = i.split('#',1)[0] 
    if not re.search(X, i): 
     continue 

    h = S.split(i,1)[0]     ## host name 
    m = S.split(i,1)[-1]    ## MAC address 
    mmap[h] = m.strip('\t|" "') 

for j, k in mmap.iteritems(): 
    if sys.argv[1] == j: 
     if not re.search(X.replace('zA-Z','fA-F'), k): 
      print "Invalid MAC address [",k,"]; nothing to do!!" 
      sys_exit() 
     else: 
      WakeOnLan(k.translate(f1_arg,':.-')) 
      print "WOL request has been sent to %s [%s]" % (j,k) 
      break 
else: 
    print "Host [%s] doesn't exist!!" % sys.argv[1] 
    sys_exit() 

내 홈 네트워크 (또는 LAN)에서 정상적으로 작동합니다. LAN 외부에서 작동하도록 스크립트를 어떻게 변경합니까? 어떤 생각이나 제안? 건배!!

답변

1

WOL 패킷이 브로드 캐스트 패킷이기 때문에 (이는 누구에게 전송 할지도 알 수 없기 때문에) 불가능합니다. 홈 라우터와 특히 ISP/네트워크 라우터는 모든 브로드 캐스트 패킷을 버립니다.이 스크립트를 실행할 때마다 전체 인터넷의 모든 컴퓨터가 패키지를 받게되어 꽤 혼란을 일으킬 수 있습니다.

모든 컴퓨터를 켜고 해당 응용 프로그램에서 WOL 패킷을 보내도록 WAN에서 실행중인 컴퓨터에 작은 응용 프로그램을 작성하면됩니다. 그러나 이것은 인터넷 접속이 가능한 컴퓨터가 항상 켜져 있어야합니다.

+0

인터넷에 라우터 IP 주소를 사용하고 존재하지 않는 LAN IP 주소로 NAT/포트 전달을 사용할 수 있다고하는 게시물이 여러 개있었습니다. 건배!! – MacUsers

+0

방법을 찾으면 여기에 모두 알려주십시오 :). –

+0

그냥 찾았습니다 (게시하기 전에 검색해서 시도 했어야합니다) : http : // www.schuetzler.net/blog/4/first-python-program-wake-on-wan'은 아직 테스트하지 않았습니다. . – MacUsers

1

10 개의 비 순차 포트 ​​중 하나를 선택하여 LAN상의 컴퓨터로 패킷을 전달하도록 라우터를 구성하십시오.

포트 트리거 시퀀스를 생성하기 위해 GMT Time + 해시라고 말한 몇 가지 체계를 고안합니다.

해당 네트워크 내의 명령 상자에서 python 프로그램 (scappy 사용)을 사용하여 일련의 syn 패킷을 수신합니다.

리스너 코드는 다음 tcpdump와 구문과 유사 할 것입니다 : 그냥 SYN 패킷을 캡처

sudo tcpdump -ni eth0 'tcp[tcpflags] & (tcp-syn) !=0' 

.

당신의 프로그램은 거기에 앉아서 오른쪽 syn 시퀀스를 기다리고 있습니다. 시퀀스를 수신하면 WOL 스크립트가 실행됩니다.

완료.

포트를 열지 않으려는 경우 스크립트는 대신 원격 웹 사이트를 폴링하여 변경 사항을 기다릴 수 있습니다. 또는 이메일을 통해 가져온 이메일을 수신합니다.

생각을 더하면 조명을 켜거나 TV를 부팅하는 등의 멋진 작업을 할 수 있습니다.

+0

유망한 소리. 내가 다시 여기에보고 해 줄거야. 건배!! – MacUsers