Debian网络设置脚本


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))
 

相关内容

    暂无相关文章