안녕하세요, 인터페이스를 삭제하고 MAC 주소를 변경한 후 다시 불러오는 bash 스크립트를 만들었습니다.
#!/bin/bash
INTERFACE_STATUS=$( cat /sys/class/net/eth0/operstate )
echo "$INTERFACE_STATUS"
if [ "$INTERFACE_STATUS" == "up" ]
then
echo "Putting down eth0"
sudo ifconfig eth0 down
# putting down eth0 works only when I sleep 10 seconds after using command
#sleep 10
echo "$( cat /sys/class/net/eth0/operstate )"
# TRIES=0
# while [ "$( cat /sys/class/net/eth0/operstate )" == "up" ]
# do
# sleep 1
# TRIES=$(($TRIES + 1))
# if [ "$TRIES" == "7" ]
# then
# echo Could not put down eth0
# exit 1
# fi
# done
fi
sudo ifconfig eth0 hw ether "91:91:91:91:91:91"
sudo ifconfig eth0 up
문제는 그것이 작동하지 않는다는 것입니다. drop 후 바로 eth0 /sys/class/net/eth0/operstate
으로 바뀌었는데 down
아직 닫히지 않은 것 같습니다. 인터페이스 eth0을 삭제하는 데 약 10초가 걸렸으므로 이를 작동하게 하는 유일한 방법은 sleep 10
eth0을 삭제한 후 추가하는 것이었습니다.
그래서 내 질문은 eht0이 실제로 닫혔는지 확인하는 방법입니다.
//편집하다
ifconfig eth0 up
새로운 MAC 주소를 얻지 못하기 때문에 명령이 매우 초기에 사용된 것과 같습니다 . 내려놓고 10초 정도 기다렸다가 MAC를 변경한 다음 다시 내려놔야 합니다. eth0을 삭제하는 데 몇 초가 걸릴 것으로 생각되며 너무 일찍 다시 삭제하면 작동하지 않습니다.
//편집 2
MAC 주소를 다시 확인해 보니 바뀐 것 같은데, 구글에서 ping을 해보니 알 수 없는 호스트가 나오니까 지금은 DNS 관련이 아닐까 싶습니다. 그러나 동일한 접근 방식이 sleep 10
작동합니다.
// 편집 3
스크립트를 사용한 후 sleep 10
ping을 사용해 보았습니다.
piotrek@piotrek-Vostro-2520:~$ ping 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:74297 errors:0 dropped:0 overruns:0 frame:0
TX packets:38597 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)0
collisions:0 txqueuelen:1000
RX bytes:32417366 (32.4 MB) TX bytes:5201537 (5.2 MB)
//4개 요약 편집
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
PING 212.77.100.101 (212.77.100.101) 56(84) bytes of data.
64 bytes from 212.77.100.101: icmp_req=1 ttl=246 time=8.91 ms
64 bytes from 212.77.100.101: icmp_req=2 ttl=246 time=8.76 ms
64 bytes from 212.77.100.101: icmp_req=3 ttl=246 time=8.52 ms
^C
--- 212.77.100.101 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.523/8.734/8.917/0.194 ms
왜 sleep 10
중요 함?
// 편집 5
이상해집니다. 제가 사용하면 아주 잘 작동합니다 sleep
. 없이 시도해보니 sleep
IP는 괜찮은 것 같고 인터페이스도 뜬 것 같은데 네트워크가 안되네요. 몇 초 후에 삭제하려고 하면 eth0
내 sudo ifconfig eth0 down
OS(ubuntu 12.10)가 자동으로 내 장치에 다시 연결됩니다.이전 MAC 주소새로운 IP를 얻었습니다. 두 번째 사용 후에 sudo ifconfig eth0 down
는 완전히 내려놓을 수 있었습니다 eth0
.
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sleep 10; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:439341 errors:0 dropped:0 overruns:0 frame:0
TX packets:224187 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:400718780 (400.7 MB) TX bytes:26246307 (26.2 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down; sudo ifconfig eth0 hw ether 08:3e:8e:2d:36:55 ; sudo ifconfig eth0 up
piotrek@piotrek-Vostro-2520:~$ ping -n 212.77.100.101
connect: Network is unreachable
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 08:3e:8e:2d:36:55
inet addr:10.36.253.241 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::a3e:8eff:fe2d:3655/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:439656 errors:0 dropped:0 overruns:0 frame:0
TX packets:224321 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:400827185 (400.8 MB) TX bytes:26267012 (26.2 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig
eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc
inet addr:10.36.253.122 Bcast:10.36.253.255 Mask:255.255.255.0
inet6 addr: fe80::e2db:55ff:fe97:decc/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:440302 errors:0 dropped:0 overruns:0 frame:0
TX packets:224862 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:401129508 (401.1 MB) TX bytes:26323176 (26.3 MB)
piotrek@piotrek-Vostro-2520:~$ sudo ifconfig eth0 down
piotrek@piotrek-Vostro-2520:~$ ifconfig eth0
eth0 Link encap:Ethernet HWaddr e0:db:55:97:de:cc
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:440437 errors:0 dropped:0 overruns:0 frame:0
TX packets:224881 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:401147424 (401.1 MB) TX bytes:26326068 (26.3 MB)
//편집 6
@Moreaki가 제안한 솔루션을 시도했지만 동일한 현상이 발생합니다. 스크립트는 약 1초 동안 실행되지만 사용 후 네트워크에 액세스할 수 없습니다. @Moreaki의 코드는 다음과 같습니다.
#!/usr/bin/env bash
INTF=eth0
INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate)
echo "$INTERFACE_STATUS"
if [ "$INTERFACE_STATUS" == "up" ]; then
echo "Putting down ${INTF}"
# if you need to remove all IP addresses associated with ${INTF}
sudo ip addr flush dev ${INTF}
# set the interface status down
sudo ip link set dev ${INTF} down
# flush neighbour cache
sudo ip neigh flush dev ${INTF}
# flush routing cache entries pertaining to ${INTF}
sudo ip route flush table cache dev ${INTF}
echo "New state: $(cat /sys/class/net/${INTF}/operstate)"
fi
sudo ip link set dev ${INTF} address "08:3e:8e:2d:36:55"
sudo ip link set dev ${INTF} up
그것을 사용하고 나면 다음과 같은 결과를 얻습니다.
piotrek@piotrek-Vostro-2520:~$ ./mac_test.sh
up
Putting down eth0
New state: down
핑을 시도한 후:
piotrek@piotrek-Vostro-2520:~$ ping google.com
ping: unknown host google.com
piotrek@piotrek-Vostro-2520:~$ ping 8.8.8.8
connect: Network is unreachable
//편집 7
@Moreaki의 라우팅 스크립트를 사용하여 Mac 주소를 변경하기 전의 라우팅은 다음과 같습니다.
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
default 10.36.253.1 10.36.253.122 eth0 main
10.36.253.0/24 0.0.0.0 10.36.253.122 eth0 main
169.254.0.0/16 0.0.0.0 10.36.253.122 eth0 main
다음을 사용하여 MAC 주소를 변경한 후내 스크립트가 10초 지연되었습니다.:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
default 10.36.253.1 10.36.253.241 eth0 main
10.36.253.0/24 0.0.0.0 10.36.253.241 eth0 main
169.254.0.0/16 0.0.0.0 10.36.253.241 eth0 main
@Moreaki 스크립트를 사용한 후 라우팅:
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
@Moreaki도 해당 줄에 주석을 달 것을 제안했지만 sudo ip addr flush dev ${INTF}
여전히 이해가 됩니다 connect: Network is unreachable
. 주석 처리된 줄이 포함된 스크립트를 사용한 후 내 라우팅은 다음과 같습니다.
piotrek@piotrek-Vostro-2520:~$ ./routing.sh
Destination Gateway Source Iface R_Type RT_table
10.36.253.0/24 0.0.0.0 10.36.253.122 eth0
답변1
인터페이스 닫기 지연은 인터페이스의 드라이버 및/또는 하드웨어와 관련이 있을 수 있습니다. 이것이 맞다면 드라이버나 하드웨어가 실제로 인터페이스를 닫았는지 알 수 있는 표준 방법은 없습니다.
문제 해결의 나머지 부분을 읽어 보면 경쟁 프로세스가 있는 것처럼 들립니다. 특히 인터페이스 자체를 "복구"하는 부분이 그렇습니다. 인터페이스를 닫은 후 인터페이스를 실행하고 복원할 수 있는 도구가 있을까요?
감지하기가 약간 까다롭지만 불가능하지는 않습니다. 나는 당신이 그것을 감지할 수 있다고 제안하는 빠르고 쉬운 방법을 생각할 수 없습니다.
답변2
나는 지체할 필요가 없다고 생각한다. 인터페이스를 종료하기 전에 이전 MAC 주소에서 물리적으로 연결을 끊을 수 있어야 합니다. 무선 연결 중이므로 지금은 테스트할 수 없습니다. ifconfig --help를 확인하세요. 이 같은? :
ifconfig <interface> del <address>
무선 네트워크에서 연결을 끊을 때 AP의 MAC 주소를 포함한 모든 것을 지우는 작은 스크립트를 실행합니다.
sudo dhcpcd --release "$INTERFACE"
sudo iwconfig "$INTERFACE" essid off
sudo iwconfig "$INTERFACE" ap off
sudo ifconfig "$INTERFACE" down
답변3
아직 논평할 수 없으므로 내 관점이 당신이 관찰하는 행동에 대해 어느 정도 밝혀지길 바랍니다. 일반적으로 Linux에서는 인터페이스 설정을 수정하기 위해 ifconfig를 사용하지 않는 것이 좋습니다. 사실, 이 기능은 10여년 전에 "더 이상 사용되지 않습니다". 그럼에도 불구하고 배포판에서 ifconfig 및 라우팅을 계속 제공하므로 여전히 작동해야 합니다.
이 접근 방식이 현재 보고 있는 동작을 변경하는지 확인할 수 있습니까?
#!/usr/bin/env bash
INTF=eth0
INTERFACE_STATUS=$(cat /sys/class/net/${INTF}/operstate)
echo "$INTERFACE_STATUS"
if [ "$INTERFACE_STATUS" == "up" ]; then
echo "Putting down ${INTF}"
# if you need to remove all IP addresses associated with ${INTF}
sudo ip addr flush dev ${INTF}
# set the interface status down
sudo ip link set dev ${INTF} down
# flush neighbour cache
sudo ip neigh flush dev ${INTF}
# flush routing cache entries pertaining to ${INTF}
sudo ip route flush table cache dev ${INTF}
echo "New state: $(cat /sys/class/net/${INTF}/operstate)"
fi
sudo ip link set dev ${INTF} address "91:91:91:91:91:91"
sudo ip link set dev ${INTF} up
부록 1: 피드백을 읽은 후 라우팅 설정에 대한 추가 정보를 제공할 수 있습니다. 나는 10년 전에 썼던 오래된 스크립트를 찾아냈습니다. 그러면 다음과 유사한 라우팅 테이블 출력이 표시됩니다 netstat
(이 명령을 실행하려면 루트가 필요함).
#!/usr/bin/env bash
# 08/2000: Initial code to beautify iproute2 routing table output
# 08/2013: Updated it for the new decade and removed swearing.
: ${IPTOOL:=/sbin/ip}
: ${DEBUG:=0}
print_format="%-18s %-15s %-18s %-8s %-6s %-10s\n"
if [ "x$1" == "x-v" -o "x$1" == "x--verbose" ]; then
DEBUG=1
fi
dbg_log(){
if [ $DEBUG -eq 1 ]; then
echo "$*"
fi
}
printme(){
if [ "x$via" == "x" -a $src_route -eq 0 ]; then
via="0.0.0.0"
fi
if [ "x$src" == "x" ]; then
src=$(${IPTOOL} addr show dev $dev label $dev | awk '/inet/ {print $2}')
src=${src%%/*}
fi
printf "$print_format" "$net" "$via" "$src" "$dev" "$type" "$table_id"
}
eval_route(){
not_parsed=0
while read net rest; do
if [ $src_route -eq 0 ]; then
src=
type=
fi
table_id="${TABLE_ID}"
dev=
via=
set -- $rest
while [ $# -ne 0 ]; do
case $1 in
proto) shift 1;;
scope) shift 1;;
metric) shift 1;;
dev) shift 1; dev=$1;;
via) shift 1; via=$1;;
src) shift 1; src=$1
# As soon as I've figured out, how to get back the
# interface/label definition from a given src IP
# I will adjust this ugly hack. --rn, 08/2000
if [ "x${src%.*}" != "x${net%.*}" ]; then
dev=$(${IPTOOL} addr show dev $dev to $src | \
awk -v check_ip=${temp_ip%%/*} 'BEGIN {/$check_ip/} END {print $7}')
fi
;;
*) dbg_log "option $1 not parsed"; not_parsed=1;;
esac
shift 1
done
# Check for 'throw, blackhole, unreachable, prohibit'
# Since we only check for non-numeric strings, we have
# to exclude the default target too.
if [ "x${net//[0-9.]/}" == "x$net" -a "x$net" != "xdefault" ]; then
type=${net:0:2}
type=${type~~}
net=$rest
dev="all"
src="0.0.0.0/0"
not_parsed=0
fi
[ $not_parsed -eq 0 ] && printme
not_parsed=0
done < <(${IPTOOL} route show table $TABLE_ID)
}
src_route=0
printf "$print_format" "Destination" "Gateway" "Source" "Iface" "R_Type" "RT_table"
while read RULE_ID rest; do
RULE_ID=${RULE_ID//:/}
fromIP=
toIP=
TABLE_ID=
set -- ${rest}
while [ $# -ne 0 ]; do
case $1 in
from) fromIP=$2 ; shift 2;;
to) toIP=$2 ; shift 2;;
lookup) TABLE_ID=$2; shift 2;;
*) shift 1;;
esac
done
if [ $RULE_ID -ne 0 ]; then
dbg_log "+------------------[RULE: $RULE_ID]------------------+"
if [ "x$fromIP" != "xall" ]; then
src_route=1
src="$IP"
type=SR
fi
eval_route
src_route=0
fi
done < <(${IPTOOL} rule show)