Debian網絡設置腳本
001
#!/usr/bin/env python3
002
# -*- coding: UTF-8 -*-
003
"""
004
網絡設置腳本
005
在debian wheezy環境下測試通過
006
依賴命令:ip, iw, wpa_supplicant, wpa_cli, dhclient
007
注意:
008
- /etc/network/interfaces裡面僅保留lo設備配置
009
- 與Gnome Network Manager/Wicd是否沖突未知
010
"""
011
__author__ = 'M@llon'
012
__version__ = ''
013
014
import json
015
import os
016
import sys
017
import traceback
018
019
import net
020
021
022
def test(v):
023
test.result = v
024
return v
025
026
027
def connect_wireless(interface_name):
028
"""
029
連接無線
030
"""
031
ssid = None
032
while True:
033
ssid = input('Enter SSID, RETURN to scan: ')
034
if not ssid:
035
for s in net.get_ssids(interface_name):
036
print(' %s' % s)
037
else:
038
break
039
040
sec = input('Select security method Open/WEP/WPA [0,1,2]: ')
041
if sec == '0':
042
net.connect_wireless(interface_name, ssid)
043
elif sec == '1':
044
keys = input('Enter comma separated keys: ').split(',')
045
net.connect_wireless_with_wep(interface_name, ssid, keys)
046
elif sec == '2':
047
key = input('Enter key: ')
048
net.connect_wireless_with_wpa(interface_name, ssid, key)
049
050
051
def setup_ip_gateway_dns(interface_name):
052
"""
053
手工設置IP地址、默認網關和DNS
054
"""
055
if test(input('Enter comma separated ip addresses: ')):
056
ip_addresses = test.result.split(',')
057
net.set_ip_addresses(interface_name, ip_addresses)
058
if test(input('Enter gateway address: ')):
059
ip_address = test.result
060
net.set_default_route(interface_name, ip_address)
061
if test(input('Enter comma separated dns addresses: ')):
062
name_servers = test.result.split(',')
063
net.set_name_servers(name_servers)
064
065
066
def load_presets(interfaces):
067
"""
068
加載預設
069
"""
070
presets_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'net-config-presets.json')
071
with open(presets_filename, encoding='utf-8') as fp:
072
presets = json.load(fp)
073
for n in presets:
074
print(' %s' % n)
075
076
preset_name = input('Enter preset name: ')
077
078
preset = presets.get(preset_name)
079
if not preset:
080
return
081
082
# 首先清理當前設置
083
net.cleanup_all(interfaces)
084
085
# 設置網絡接口
086
ifaces = preset.get('interfaces')
087
for if_name in ifaces:
088
iface = ifaces[if_name]
089
090
# 啟用接口
091
net.enable_interface(if_name)
092
093
# 連接無線網
094
ssid = iface.get('ssid')
095
if ssid:
096
sec = iface.get('security')
097
if not sec:
098
net.connect_wireless(if_name, ssid)
099
elif sec == 'wep':
100
keys = iface.get('keys')
101
if keys:
102
net.connect_wireless_with_wep(if_name, ssid, keys)
103
elif sec == 'wpa':
104
key = iface.get('key')
105
if key:
106
net.connect_wireless_with_wpa(if_name, ssid, key)
107
108
# 設置IP地址
109
ip_addresses = iface.get('ip_addresses')
110
if ip_addresses == 'dynamic':
111
# 多個接口的DHCP,後者可能會覆蓋前者
112
net.set_dhcp(if_name)
113
elif isinstance(ip_addresses, list):
114
net.set_ip_addresses(if_name, ip_addresses)
115
116
# 設置默認路由,可能會覆蓋DHCP設置
117
default_route = preset.get('default_route')
118
if default_route:
119
route_if_name = default_route.get('interface_name')
120
route_ip_addr = default_route.get('ip_address')
121
if route_if_name and route_ip_addr:
122
net.set_default_route(route_if_name, route_ip_addr)
123
124
# 設置DNS,可能會覆蓋DHCP設置
125
name_servers = preset.get('name_servers')
126
if name_servers:
127
net.set_name_servers(name_servers)
128
129
130
if __name__ == '__main__':
131
# 提升到root權限
132
if os.geteuid():
133
args = [sys.executable] + sys.argv
134
# 下面兩種寫法,一種使用su,一種使用sudo,都可以
135
#os.execlp('su', 'su', '-c', ' '.join(args))
136
os.execlp('sudo', 'sudo', *args)
137
138
# 顯示根菜單
139
while True:
140
try:
141
interfaces = net.get_interfaces()
142
143
os.system('clear')
144
net.print_state(interfaces, net.get_default_route(), net.get_name_servers())
145
except Exception as ex:
146
traceback.print_exc()
147
break
148
149
print('Root Menu:')
150
print(' 0 - Quit')
151
print(' 1 - cleanup all settings')
152
print(' 2 - enable interface')
153
print(' 3 - disable interface')
154
print(' 4 - connect interface')
155
print(' 5 - disconnect interface')
156
print(' 6 - setup ip, gateway and dns using dhcp')
157
print(' 7 - setup ip, gateway and dns manually')
158
print(' 8 - load presets')
159
print()
160
161
try:
162
choice = input('Enter your choice: ')
163
if choice == '0':
164
break
165
elif choice == '1':
166
if input('Are you sure? [y/n]: ').lower() == 'y':
167
net.cleanup_all(interfaces)
168
elif choice in ('2', '3', '4', '5', '6', '7'):
169
name = input('Enter interface name: ')
170
if name in interfaces:
171
if choice == '2':
172
if not interfaces[name]['enabled']:
173
net.enable_interface(name)
174
elif choice == '3':
175
if interfaces[name]['enabled']:
176
if interfaces[name]['connected'] and interfaces[name]['wireless']:
177
net.disconnect_wireless(name)
178
net.disable_interface(name)
179
elif choice == '4':
180
if interfaces[name]['enabled'] and interfaces[name]['wireless'] and (
181
not interfaces[name]['connected']):
182
connect_wireless(name)
183
elif choice == '5':
184
if interfaces[name]['connected'] and interfaces[name]['wireless']:
185
net.disconnect_wireless(name)
186
elif choice == '6':
187
if interfaces[name]['connected']:
188
net.set_dhcp(name)
189
elif choice == '7':
190
setup_ip_gateway_dns(name)
191
elif choice == '8':
192
load_presets(interfaces)
193
except KeyboardInterrupt as ex:
194
print()
195
break
196
except Exception as ex:
197
traceback.print_exc()
198
input('Press any key to continue...')
net.py
001
#!/usr/bin/env python3
002
# -*- coding: UTF-8 -*-
003
"""
004
常用網絡命令的python封裝
005
"""
006
__author__ = 'M@llon'
007
__version__ = ''
008
009
import os
010
import re
011
012
013
def test(v):
014
test.result = v
015
return v
016
017
018
def get_interfaces():
019
"""
020
獲取所有網絡接口信息
021
遇到任何錯誤均拋出異常
022
"""
023
interfaces = dict()
024
025
# 獲取接口名、索引號、啟停狀態、連接狀態、硬件地址、IPv4地址
026
for line in os.popen('ip -o addr show'):
027
if test(re.match('^(\d+):\s+(\w+):\s+<(.+?)>\s+.+?state\s+(\w+)\s+.+?link/(\w+)\s+(\S+)\s+.+?\n$', line)):
028
m = test.result
029
# 這些標記的含義參見“/linux/if.h”中的“IFF_...”宏
030
flags = m.group(3).split(',')
031
# 去掉回環接口
032
if 'LOOPBACK' in flags:
033
continue
034
interfaces[m.group(2)] = {
035
'index': int(m.group(1)),
036
'enabled': 'UP' in flags,
037
'connected': {'UP': True, 'DOWN': False}.get(m.group(4)),
038
'hardware_address': m.group(6),
039
'wireless': False,
040
'ip_addresses': list()
041
}
042
elif test(re.match('^\d+:\s+(\w+)\s+inet\s+(\S+)\s+.+?\n$', line)):
043
m = test.result
044
name = m.group(1)
045
interface = interfaces.get(name)
046
if not interface:
047
# 此處就排除了上面去掉的接口,例如loopback接口
048
continue
049
interface['ip_addresses'].append(m.group(2))
050
051
# 獲取無線類型的接口
052
for line in os.popen('iw dev'):
053
if test(re.match('^\s+Interface\s+(\w+)\s*?\n$', line)):
054
# 接口是否為wireless
055
interfaces[test.result.group(1)]['wireless'] = True
056
057
# 獲取無線類型的接口的連接信息
058
for name in interfaces:
059
interface = interfaces[name]
060
if interface['wireless']:
061
for line in os.popen('iw dev %s link' % name):
062
# 此處也可以通過“Connected ...”行判斷是否已連接,但是上面已經判斷了
063
if test(re.match('^\s+SSID:\s+(\S+)\s*?\n$', line)):
064
# 獲取SSID
065
interface['ssid'] = test.result.group(1)
066
067
return interfaces
068
069
070
def get_default_route():
071
"""
072
獲取默認路由信息
073
"""
074
default_route = None
075
076
for line in os.popen('ip route show'):
077
if test(re.match('^\s*default\s+via\s+(\S+)\s+dev\s+(\S+)\s*\n$', line)):
078
m = test.result
079
default_route = {
080
'ip_address': m.group(1),
081
'interface_name': m.group(2)
082
}
083
break
084
085
return default_route
086
087
088
def get_name_servers():
089
"""
090
獲取域名服務器IP地址列表
091
"""
092
name_servers = list()
093
094
for line in open('/etc/resolv.conf'):
095
if test(re.match('^\s*nameserver\s+(\S+)\s*\n$', line)):
096
name_servers.append(test.result.group(1))
097
098
return name_servers
099
100
101
def print_state(interfaces, default_route, name_servers):
102
"""
103
打印所有網絡接口、路由以及DNS信息
104
"""
105
# 網絡接口
106
print('Network Interfaces:')
107
print(' %10s %8s %17s %s' % (
108
'name',
109
'type',
110
'mac address',
111
'state',
112
))
113
print(' ---------- -------- ----------------- -----')
114
for name in interfaces:
115
interface = interfaces[name]
116
state = list()
117
if interface['enabled']:
118
state.append('enabled')
119
if interface['connected']:
120
state.append('connected')
121
if test(interface.get('ssid')):
122
state.append('ssid:%s' % test.result)
123
if len(interface['ip_addresses']):
124
state.append('ip:%s' % ','.join(interface['ip_addresses']))
125
print(' %10s %8s %17s %s' % (
126
name,
127
'wireless' if interface['wireless'] else 'wired',
128
interface['hardware_address'],
129
', '.join(state) if len(state) else 'N/A'
130
))
131
print()
132
133
# 默認路由
134
print('Default Gateway:')
135
if default_route:
136
print(' ---> %s ---> %s' % (default_route['interface_name'], default_route['ip_address']))
137
else:
138
print(' N/A')
139
print()
140
141
# DNS
142
print('DNS:')
143
if len(name_servers):
144
print(' %s' % ', '.join(name_servers))
145
else:
146
print(' N/A')
147
print()
148
149
150
def cleanup_all(interfaces):
151
"""
152
清理網絡接口所有的設置、默認路由以及DNS
153
"""
154
# 結束“supplicant”進程
155
os.system('killall wpa_supplicant')
156
157
# 禁用所有網絡接口,刪除所有IP地址以及路由
158
for name in interfaces:
159
os.system('ip link set %s down' % name)
160
os.system('ip addr flush %s' % name)
161
162
# 刪除所有DNS地址
163
open('/etc/resolv.conf', 'w').close()
164
165
166
def enable_interface(interface_name):
167
"""
168
啟用網絡接口
169
"""
170
os.system('ip link set %s up' % interface_name)
171
172
173
def disable_interface(interface_name):
174
"""
175
禁用網絡接口
176
"""
177
os.system('ip link set %s down' % interface_name)
178
179
180
def get_ssids(interface_name):
181
"""
182
掃描SSID
183
"""
184
ssids = list()
185
186
for line in os.popen('iw dev %s scan' % interface_name):
187
if test(re.match('^\s+SSID:\s+(\S+)\s*?\n$', line)):
188
ssids.append(test.result.group(1))
189
190
return ssids
191
192
193
def connect_wireless(interface_name, ssid):
194
"""
195
連接非加密的無線網
196
"""
197
os.system('iw dev %s connect -w %s' % (interface_name, ssid))
198
199
200
def connect_wireless_with_wep(interface_name, ssid, keys):
201
"""
202
連接WEP加密的無線網
203
"""
204
os.system('iw dev %s connect -w %s key %s' % (interface_name, ssid, ' '.join(keys)))
205
206
207
def connect_wireless_with_wpa(interface_name, ssid, key):
208
"""
209
連接WPA加密的無線網
210
"""
211
os.system(
212
'wpa_supplicant -i %s -D nl80211,wext -s -B -P /var/run/wpa_supplicant.%s.pid -C /var/run/wpa_supplicant' % (
213
interface_name, interface_name
214
))
215
os.system('wpa_cli -i %s add_network' % interface_name)
216
os.system('wpa_cli -i %s set_network 0 ssid \'"%s"\'' % (interface_name, ssid))
217
os.system('wpa_cli -i %s set_network 0 key_mgmt WPA-PSK' % interface_name)
218
os.system('wpa_cli -i %s set_network 0 psk \'"%s"\'' % (interface_name, key))
219
os.system('wpa_cli -i %s enable_network 0' % interface_name)
220
221
222
def disconnect_wireless(interface_name):
223
"""
224
關閉無線連接
225
"""
226
pattern = '^\s*\S+\s+(\S+)\s+.+?wpa_supplicant.%s.pid.+?\n$' % interface_name
227
for line in os.popen('ps aux'):
228
if test(re.match(pattern, line)):
229
pid = test.result.group(1)
230
os.system('kill -9 %s' % pid)
231
os.system('iw dev %s disconnect' % interface_name)
232
233
234
def set_dhcp(interface_name):
235
"""
236
使用DHCP設置接口
237
"""
238
os.system('dhclient -r %s' % interface_name)
239
os.system('dhclient %s' % interface_name)
240
241
242
def set_ip_addresses(interface_name, ip_addresses):
243
"""
244
設置某網絡接口的IP地址
245
"""
246
os.system('ip addr flush %s' % interface_name)
247
for ip_address in ip_addresses:
248
os.system('ip addr add %s dev %s' % (ip_address, interface_name))
249
250
251
def set_default_route(interface_name, ip_address):
252
"""
253
設置默認路由
254
"""
255
os.system('ip route del default')
256
os.system('ip route add default via %s dev %s' % (ip_address, interface_name))
257
258
259
def set_name_servers(name_servers):
260
"""
261
設置域名服務器地址
262
"""
263
with open('/etc/resolv.conf', 'w') as fp:
264
for name_server in name_servers:
265
fp.write('nameserver %s%s' % (name_server, os.linesep))