207 lines
No EOL
7.4 KiB
Python
207 lines
No EOL
7.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import ssl
|
|
import sys
|
|
import argparse
|
|
from datetime import datetime
|
|
|
|
try:
|
|
from librouteros import connect
|
|
except ImportError:
|
|
print("Error: librouteros module not found")
|
|
print("Install with: pip install librouteros")
|
|
sys.exit(1)
|
|
|
|
def get_router_config(host, username='grahamro', password='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', port=8729):
|
|
"""
|
|
Get full router configuration export
|
|
|
|
Args:
|
|
host: IP address or hostname of the router
|
|
username: Router username
|
|
password: Router password
|
|
port: API-SSL port (default: 8729)
|
|
|
|
Returns:
|
|
Configuration export string
|
|
"""
|
|
|
|
print(f"=== Connecting to MikroTik Router ({host}) ===\n")
|
|
|
|
# SSL context for secure connection
|
|
ctx = ssl.create_default_context()
|
|
ctx.check_hostname = False
|
|
ctx.verify_mode = ssl.CERT_NONE
|
|
|
|
try:
|
|
# Connect to router
|
|
api = connect(
|
|
username=username,
|
|
password=password,
|
|
host=host,
|
|
port=port,
|
|
ssl_wrapper=ctx.wrap_socket
|
|
)
|
|
|
|
print("✓ Connected successfully\n")
|
|
print("Exporting configuration...")
|
|
|
|
# Get router identity first
|
|
try:
|
|
identity_data = api('/system/identity/print')
|
|
if identity_data:
|
|
identity = identity_data[0].get('name', 'router')
|
|
print(f"Router identity: {identity}")
|
|
except:
|
|
identity = 'router'
|
|
|
|
# Export configuration
|
|
# Note: /export returns the config in a specific format
|
|
try:
|
|
# For RouterOS API, we need to get specific sections
|
|
config_sections = []
|
|
|
|
# Get IP addresses
|
|
print("\nGetting IP configuration...")
|
|
ip_addresses = api('/ip/address/print')
|
|
|
|
# Get IP pools
|
|
print("Getting IP pools...")
|
|
try:
|
|
ip_pools = api('/ip/pool/print')
|
|
except:
|
|
ip_pools = []
|
|
|
|
# Get PPPoE servers
|
|
print("Getting PPPoE servers...")
|
|
try:
|
|
pppoe_servers = api('/interface/pppoe-server/server/print')
|
|
except:
|
|
pppoe_servers = []
|
|
|
|
# Get PPP profiles
|
|
print("Getting PPP profiles...")
|
|
try:
|
|
ppp_profiles = api('/ppp/profile/print')
|
|
except:
|
|
ppp_profiles = []
|
|
|
|
# Get firewall NAT rules
|
|
print("Getting NAT rules...")
|
|
try:
|
|
nat_rules = api('/ip/firewall/nat/print')
|
|
except:
|
|
nat_rules = []
|
|
|
|
# Get DHCP servers
|
|
print("Getting DHCP configuration...")
|
|
try:
|
|
dhcp_servers = api('/ip/dhcp-server/print')
|
|
dhcp_networks = api('/ip/dhcp-server/network/print')
|
|
except:
|
|
dhcp_servers = []
|
|
dhcp_networks = []
|
|
|
|
# Build configuration summary
|
|
config = f"# Configuration for {identity} ({host})\n"
|
|
config += f"# Exported on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
|
|
|
# IP Addresses
|
|
config += "# IP Addresses\n"
|
|
for addr in ip_addresses:
|
|
if not addr.get('disabled', False) and not addr.get('dynamic', False):
|
|
config += f"/ip address add address={addr['address']} interface={addr.get('interface', '')} "
|
|
if addr.get('comment'):
|
|
config += f"comment=\"{addr['comment']}\""
|
|
config += "\n"
|
|
|
|
# IP Pools
|
|
if ip_pools:
|
|
config += "\n# IP Pools\n"
|
|
for pool in ip_pools:
|
|
config += f"/ip pool add name={pool['name']} ranges={pool.get('ranges', '')}\n"
|
|
|
|
# PPPoE configuration
|
|
if pppoe_servers:
|
|
config += "\n# PPPoE Servers\n"
|
|
for server in pppoe_servers:
|
|
if not server.get('disabled', False):
|
|
config += f"/interface pppoe-server server add name={server.get('service-name', '')} "
|
|
config += f"interface={server.get('interface', '')} "
|
|
if server.get('default-profile'):
|
|
config += f"default-profile={server['default-profile']} "
|
|
config += "\n"
|
|
|
|
# PPP Profiles
|
|
if ppp_profiles:
|
|
config += "\n# PPP Profiles\n"
|
|
for profile in ppp_profiles:
|
|
if profile['name'] != 'default' and profile['name'] != 'default-encryption':
|
|
config += f"/ppp profile add name={profile['name']} "
|
|
if profile.get('local-address'):
|
|
config += f"local-address={profile['local-address']} "
|
|
if profile.get('remote-address'):
|
|
config += f"remote-address={profile['remote-address']} "
|
|
config += "\n"
|
|
|
|
# NAT rules
|
|
if nat_rules:
|
|
config += "\n# NAT Rules\n"
|
|
for rule in nat_rules:
|
|
if not rule.get('disabled', False):
|
|
config += f"/ip firewall nat add chain={rule.get('chain', '')} "
|
|
if rule.get('src-address'):
|
|
config += f"src-address={rule['src-address']} "
|
|
if rule.get('dst-address'):
|
|
config += f"dst-address={rule['dst-address']} "
|
|
if rule.get('action'):
|
|
config += f"action={rule['action']} "
|
|
if rule.get('to-addresses'):
|
|
config += f"to-addresses={rule['to-addresses']} "
|
|
config += "\n"
|
|
|
|
# Close connection
|
|
api.close()
|
|
|
|
return config
|
|
|
|
except Exception as e:
|
|
print(f"Error getting configuration: {e}")
|
|
api.close()
|
|
return None
|
|
|
|
except Exception as e:
|
|
print(f"✗ Connection failed: {e}")
|
|
return None
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Export configuration from a MikroTik router')
|
|
parser.add_argument('host', help='IP address or hostname of the router')
|
|
parser.add_argument('--username', '-u', default='grahamro', help='Router username')
|
|
parser.add_argument('--password', '-p', default='cFKhz8q5gPLoucMbcT1Iy58r3IXgc3', help='Router password')
|
|
parser.add_argument('--port', type=int, default=8729, help='API-SSL port (default: 8729)')
|
|
parser.add_argument('--output', '-o', help='Output filename')
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Get router config
|
|
config = get_router_config(args.host, args.username, args.password, args.port)
|
|
|
|
if config:
|
|
if args.output:
|
|
with open(args.output, 'w') as f:
|
|
f.write(config)
|
|
print(f"\n✓ Configuration exported to: {args.output}")
|
|
else:
|
|
print("\n=== Configuration Export ===")
|
|
print(config)
|
|
|
|
return 0
|
|
else:
|
|
print("\n✗ Failed to export configuration")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |