def reconfItem(self, iface, data): wanDevices = self.sysconf.WANDevices defaults = [] for d in wanDevices.get(iface, {}).get('pppd', []): # If we append these, it's impossible to reconfigure them if d not in ['defaultroute', 'usepeerdns']: defaults.append(d) if data['defaultRoute']: defaults.append('defaultroute') if data['defaultDNS']: defaults.append('usepeerdns') seg = { 'pppd': defaults, 'username': data['username'], 'password': data['password'], 'link': data['link'], 'plugins': 'pppoe' } wanDevices[iface] = seg self.sysconf.WANDevices = wanDevices if data['localOnly']: self.sysconf.LocalRoute = iface else: if self.sysconf.LocalRoute == iface: self.sysconf.LocalRoute = '' if data['createNAT']: shorewall = self.sysconf.Shorewall masq = shorewall.get('masq') if not (iface in masq): masq[iface] = Utils.getLans(self.sysconf) shorewall['masq'] = masq self.sysconf.Shorewall = shorewall WebUtils.system('/usr/local/tcs/tums/configurator --shorewall; shorewall restart') wallZones = self.sysconf.Shorewall['zones'] s = self.sysconf.Shorewall # Remove interface from any and all zones for i,v in wallZones.items(): newIfs = [] for k in v['interfaces']: if not (iface in k): newIfs.append(k) s['zones'][i]['interfaces'] = newIfs if data['zone']: # Add to new zone s['zones'][data['zone'].encode()]['interfaces'].append( '%s detect' % iface ) self.sysconf.Shorewall = s
def submitRoute(self, ctx, form, data): eth = self.sysconf.EthernetDevices target = None destination = data['dest'].encode() if data['gate']: gateway = data['gate'].encode() else: gateway = data['device'].encode() if '0.0.0.0/0' in destination: destination = u'default' if 'eth' in self.sysconf.WANPrimary: target = self.sysconf.WANPrimary else: target = Utils.getLans(self.sysconf)[0] if (not target) and data['gate']: # Dunno where to go... Look at gateway and make an intelligent choice for iface, net in Utils.getLanNetworks(self.sysconf).items(): print data['gate'] if Utils.matchIP(net, gateway): # Gateway matches this interface local-link target = iface if not target: # Still nothing, go for broke target = Utils.getLans(self.sysconf)[0] routes = eth[target].get('routes', []) routes.append((destination, gateway)) eth[target]['routes'] = routes self.sysconf.EthernetDevices = eth def next(_): return url.root.child('Routing') return applySettings().addCallback(next)
def submitRoute(self, ctx, form, data): eth = self.sysconf.EthernetDevices target = None destination = data['dest'].encode("ascii", "replace").lower() if data['gate']: gateway = data['gate'].encode("ascii", "replace") if data['device']: target = data['device'].encode("ascii", "replace") else: gateway = data['device'].encode("ascii", "replace") if '0.0.0.0/0' in destination: destination = 'default' if destination == 'default': # Purge existing default routes, if any for dev, items in eth.items(): oldRoutes = items.get('routes', []) newRoutes = [] for dst, gw in oldRoutes: if dst == "default": continue newRoutes.append((dst, gw)) eth[dev]['routes'] = newRoutes if (not target) and data['gate']: # Dunno where to go... Look at gateway and make an intelligent choice for iface, net in Utils.getLanNetworks(self.sysconf).items(): print data['gate'] if Utils.matchIP(net, gateway): # Gateway matches this interface local-link target = iface if not target: # Still nothing, go for broke - these will be added to Quagga anyways target = Utils.getLans(self.sysconf)[0] routes = eth[target].get('routes', []) routes.append((destination, gateway)) eth[target]['routes'] = routes self.sysconf.EthernetDevices = eth def next(_): return url.root.child('Routing') return applySettings().addCallback(next)
def lanTest(self): ha = self.sysconf.General.get('ha', {}) flan = Utils.getLans(self.sysconf)[0] lanIP = self.sysconf.EthernetDevices[flan].get('network', '192.168.0.0/24') myIP = self.sysconf.EthernetDevices[flan].get( 'ip', '192.168.0.0/24').split('/')[0] print lanIP, myIP def lanScan(res): print res for i in res.split('\n'): if i[:5] != "Host:": continue n = i.split() ip = n[1] host = n[2][1:-1] if ip in ha.keys(): ha[ip]['status'] = 'Online' else: ha[ip] = { 'status': 'Online', 'topology': "Not Configured", 'name': host or ip, } if ip == myIP: ha[ip]['status'] = "Me" ha[ip]['name'] = "" servers = [ map(unicode, [v['name'], v['topology'], v.get('status', 'Offline'), k]) for k, v in ha.items() ] return servers loc = 'nmap -sS -p 9682,54322 -oG - %s 2>&1 | grep "9682/open/tcp" | grep "54322/open/tcp"' % ( lanIP.encode("ascii", "replace")) print loc return WebUtils.system(loc).addBoth(lanScan)
def writeConfig(self, *a): lans = Utils.getLans(config) wans = Utils.getWans(config) lanifaces = ','.join(["%s:100" % i for i in lans]) wanifaces = ','.join( ["%s:%s" % (iface, 201 + c) for c, iface in enumerate(wans)]) ifaces = "%s,%s" % (lanifaces, wanifaces) ifaces = ifaces.strip( ',') # Take care of any trailing commas if wanifaces is empty # Declare the configuration fprobe = """ #fprobe-ulog configuration generated by TUMS INTERFACE="%s" FLOW_COLLECTOR="127.0.0.1:9685" OTHER_ARGS="-U2" """ % ifaces l = open('/etc/default/fprobe-ulog', 'wt') l.write(fprobe) l.close()
def writeConfig(self, *a): if not config.General.get('xen'): # No Xen config return if not config.General['xen'].get('enabled'): # Disabled return self.checkInstall() XenConf = config.General['xen'].get('config', {}) conf = """ # -*- sh -*- # Vulani Xen configuration (network-script 'network-bridge netdev=%(lanPrimary)s') (network-script network-dummy) (vif-script vif-bridge) (dom0-min-mem 196) (dom0-cpus 0) (vnc-listen '%(lanPrimaryIp)s' """ % { 'lanPrimaryIp': Utils.getLanIPs(config)[0], 'lanPrimary': Utils.getLans(config)[0] } # Seek out our latest Xen kernel lines = os.open('ls /boot/ | grep xen-vserver | grep -v ".bak$"') kern = "vmlinuz-2.6.18-6-xen-vserver-686" init = "initrd.img-2.6.18-6-xen-vserver-686" knum = 2 * 6 * 18 * 6 inum = 2 * 6 * 18 * 6 for n in lines.read(): line = n.strip('\n') if not ('vmlinuz' in line or 'initrd' in line): # avoid things that might break this logic continue p = line.split('-') # Make a big number from the version ver = reduce(lambda x, y: x * y, [int(i) for i in p[1].split('.')]) * int(p[2]) # Make sure this is the biggest version if "vmlinuz" in line: if ver > knum: kern = line knum = ver if "initrd" in line: if ver > knum: init = line inum = ver toolconf = """ # Vulani Xen-tools configuration dir = /storage/virtual_machines size = 10Gb memory = 128Mb swap = 128Mb fs = ext3 dist = etch image = sparse dhcp = 1 passwd = 1 kernel = /boot/%(xenKern)s initrd = /boot/%(xenInit)s mirror = http://debian.mirror.ac.za/debian/ """ % { 'xenKern': kern, 'xenInit': init } defaults = """ # Vulani Xen defaults XENDOMAINS_SYSRQ="" XENDOMAINS_USLEEP=100000 XENDOMAINS_CREATE_USLEEP=5000000 XENDOMAINS_MIGRATE="" XENDOMAINS_SAVE=/var/lib/xen/save XENDOMAINS_SHUTDOWN="--halt --wait" XENDOMAINS_SHUTDOWN_ALL="--all --halt --wait" XENDOMAINS_RESTORE=true XENDOMAINS_AUTO=/etc/xen/auto XENDOMAINS_AUTO_ONLY=false XENDOMAINS_STOP_MAXWAIT=300 """ Utils.writeConf('/etc/xend-config.sxp', conf, None) Utils.writeConf('/etc/xen-tools/xen-tools.conf', toolconf, None) Utils.writeConf('/etc/default/xendomains', defaults, None)
def writeConfig(self, *a): rules = "" ruleList = [ [1, 'Ping/ACCEPT all all'], [1, 'AllowICMPs all all'], [1, 'ACCEPT all all udp 33434:33463'], ] ruleList.extend(config.Shorewall.get('redirect', [])) ruleList.extend(config.Shorewall.get('rules', [])) ruleList.extend(config.Shorewall.get('dnat', [])) for enable, rule in ruleList: if not enable: rules += "#" rules += "%s\n" % rule if config.Shorewall.get('blockp2p', False): rules += "REJECT all all ipp2p:tcp\n" rules += "REJECT all all ipp2p:udp\n" rules += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/rules', 'wt') l.write(rules) l.close() tos = "###############################################################################\n" tos += "#SOURCE DEST PROTOCOL SOURCE DEST TOS\n" tos += "# PORTS PORTS\n" for p, proto, t in config.Shorewall.get('qos', []): tos += "all all %s - %s %s\n" % ( proto, p, t) tos += "all all %s %s - %s\n" % ( proto, p, t) tos += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/tos', 'wt') l.write(tos) l.close() policies = """fw all ACCEPT loc fw ACCEPT loc loc ACCEPT\n""" interfaces = "" zones = "fw firewall\n" for zone in config.Shorewall.get('zones', {}): zoneifaces = config.Shorewall['zones'][zone]['interfaces'] policy = config.Shorewall['zones'][zone]['policy'] log = config.Shorewall['zones'][zone]['log'] zones += "%s ipv4\n" % (zone, ) policies += "%s all %s %s\n" % (zone, policy, log) for interface in zoneifaces: interfaces += "%s %s\n" % (zone, interface) for zone in Utils.getLanZones(config): if config.ProxyConfig.get('captive'): zones += "c%s:%s\n" % (zone, zone) if config.ProxyConfig.get('captiveblock'): policies += "c%s all DROP $LOG\n" % (zone, ) else: policies += "c%s all ACCEPT\n" % (zone, ) policies += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" interfaces += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" zones += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" params = "LOG=ULOG\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" # SNAT configuration nat = """############################################################################### #EXTERNAL INTERFACE INTERNAL ALL LOCAL # INTERFACES\n""" for ru in config.Shorewall.get('snat', []): nat += ru + '\n' nat += "#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/nat', 'wt') l.write(nat) l.close() # Masqeurading masq = "" for dest, sources in config.Shorewall.get('masq', {}).items(): for source in sources: if type(source) == list: # New style rule... dstnet = source[0].replace('-', '') if dstnet: dstnet = ':' + dstnet srcnet = source[1].replace('-', '') srcif = source[2].replace('-', '') if srcif: # Ignore the srcnet rule... srcnet = srcif using = source[3].replace('-', '') proto = source[4].replace('-', '') port = source[5].replace('-', '') if proto and not using: using = '-' masq += "%s%s %s %s %s %s\n" % ( dest, dstnet, srcnet, using, proto, port) else: masq += "%s %s \n" % (dest, source) masq += "#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" wl = { 'policy': policies, 'interfaces': interfaces, 'zones': zones, 'params': params, 'masq': masq } for i in wl: l = open('/etc/shorewall/%s' % i, 'wt') l.write(wl[i]) l.close() providers = "#NAME NUMBER MARK DUPLICATE INTERFACE GATEWAY OPTIONS COPY\n" i = 0 lans = ','.join(Utils.getLans(config)) for inter in config.ShorewallBalance: i += 1 interzone = config.Shorewall['zones'][ inter[0]]['interfaces'][0].split()[0] providers += "%s %s %s main %s %s %s,optional %s \n" % ( inter[0], i, i, interzone, inter[1], inter[2], lans) providers += "#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/providers', 'wt') l.write(providers) l.close() routes = "#SOURCE DEST PROVIDER PRIORITY\n" for ru in config.ShorewallSourceRoutes: if len(ru) > 2: prio = ru[2] else: prio = 1000 routes += "%s - %s %s\n" % ( ru[0], ru[1], prio) routes += "#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/route_rules', 'wt') l.write(routes) l.close() parp = """ #ADDRESS INTERFACE EXTERNAL HAVEROUTE PERSISTENT """ for arps in config.Shorewall.get('proxyarp', {}): parp += "%s %s %s no yes\n" % tuple(arps) parp += "#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/proxyarp', 'wt') l.write(parp) l.close() routes = "" # Check if there are any routes to be added for interface, defin in config.EthernetDevices.items(): for dest, gw in defin.get('routes', []): if dest != 'default': for inter in config.ShorewallBalance: # Add a route to all shorewall balancing table routes += "ip ro add %s via %s table %s\n" % (dest, gw, inter[0]) init = """use Shorewall::Chains; insert_rule $filter_table->{FORWARD}, 1, "-j ULOG --ulog-nlgroup 2"; insert_rule $filter_table->{INPUT}, 1, "-j ULOG --ulog-nlgroup 2"; insert_rule $filter_table->{OUTPUT}, 1, "-j ULOG --ulog-nlgroup 2"; 1;\n""" l = open('/etc/shorewall/initdone', 'wt') l.write(init) l.close() tcdevices = "" tcclasses = "" for dev, det in config.Shaping.items(): tcdevices += "%s %s %s\n" % (dev, det['ratein'], det['rateout']) for cls in det['classes']: tcclasses += "%s %s %s %s %s %s\n" % ( dev, cls[0], cls[1], cls[2], cls[3], cls[4]) tcclasses += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" tcrules = "" for i in config.ShaperRules: tcrules += "%s\n" % i tcrules += "\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n" l = open('/etc/shorewall/tcdevices', 'wt') l.write(tcdevices) l.write( '\n#LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE\n' ) l.close() l = open('/etc/shorewall/tcclasses', 'wt') l.write(tcclasses) l.close() l = open('/etc/shorewall/tcrules', 'wt') l.write(tcrules) l.close() ipup = """#!/bin/sh -e killall shorewall /sbin/shorewall restart /etc/init.d/quagga restart /usr/local/tcs/tums/networkManager up $1 || true exit 0\n""" l = open('/etc/ppp/ip-up.d/shorewall', 'wt') l.write(ipup) l.close() ipdown = """#!/bin/sh -e killall shorewall /sbin/shorewall restart /etc/init.d/quagga restart /usr/local/tcs/tums/networkManager down $1 || true exit 0\n""" l = open('/etc/ppp/ip-down.d/shorewall', 'wt') l.write(ipdown) l.close() os.system('chmod a+x /etc/ppp/ip-up.d/shorewall') os.system('chmod a+x /etc/ppp/ip-down.d/shorewall') # Update shorewall.conf os.system( 'cp /usr/local/tcs/tums/configs/shorewall.conf /etc/shorewall/')
def renderHTTP(self, ctx): request = inevow.IRequest(ctx) def render(data): # Set our content dispositions and write the stream request.setHeader("content-type", "image/png") request.setHeader("content-length", str(len(data))) return data width = 700 height = 64 rHeight, lHeight = 0, 0 # Internet side (left) locals = Utils.getLans(self.sysconf) wans = {} lans = {} leftSize = 0 rightSize = 0 balanceZones = {} for zone, ip, type in self.sysconf.ShorewallBalance: balance = 'balance' in type balanceZones[zone] = (balance, ip) self.balanced = [] idefer = [] for k,net in Utils.getNetworks(self.sysconf).items(): routes = {} size = 1 zone = Utils.getZone(self.sysconf, k) doneInet = False if zone in balanceZones: if balanceZones[zone][0]: self.balanced.append(k) gate = balanceZones[zone][1] if gate: # otherwise... wtf routes[('router', gate)] = {('internet', 'Internet', k):None} size = 3 else: # Get a new router icon for Link-route devices like PPPoE routes[('router', 'LINK')]= {('internet', 'Internet', k):None} for dst,gate in self.sysconf.EthernetDevices[k].get('routes', []): if (dst == 'default') and (not doneInet): if Utils.matchIP(net, gate): # The default router sits on this segment routes[('router', gate)] = {('internet', 'Internet', k): None} if 3>size: size = 3 else: # Another switch behind a router routes[('router', gate)] = {('switch', dst): None} size = 3 if k in locals: node = ('switch', net+'-'+k) lans[node] = routes if size > rightSize: rightSize = size rHeight += 64 else: node = ('switch', net+'-'+k) if k in self.balanced: idefer.append((node, routes)) else: wans[node] = routes if size > leftSize: leftSize = size lHeight += 64 for k,v in self.sysconf.WANDevices.items(): routes = {} zone = Utils.getZone(self.sysconf, k) lHeight += 64 if zone in balanceZones: if balanceZones[zone][0]: self.balanced.append(k) gate = balanceZones[zone][1] # Get a new router icon for Link-route devices like PPPoE routes[('internet', 'Internet', k)] = None if 'defaultroute' in v.get('pppd', []): routes[('internet', 'Internet', k)] = None else: if k == self.sysconf.LocalRoute: # Put a ZA flag here... routes[('internet', 'Internet', k)] = None if not routes: routes[('switch', 'Cloud', k)] = None node = ('netlink', 'PPP '+k[-1]) wans[node] = routes # Figure out our best dimensions mHeight = max([rHeight, lHeight]) print "Total height", mHeight, rHeight, lHeight height = mHeight # Configure our context surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height+16) c = cairo.Context(surface) c.set_line_width(2) vloc = (width/2, height/2) # Center of image (where vulani goes) wans = [i for i in wans.items()] wans.extend(idefer) #for node, routes in idefer: # wans.append((node] = routes totalBreadth = leftSize + rightSize + 1 print "Total width", totalBreadth, leftSize, rightSize xSteps = (width)/totalBreadth if leftSize: if leftSize == rightSize: vx = width/2 else: vx = (xSteps * leftSize) + 56 else: vx = 56 vloc = (vx, height/2) self.drawLater = [] posX = 64 # Wans (left) self.iLoc = None self.parseTree(c, wans, height, 0, vloc[0]-xSteps, vloc, -xSteps) # Lans (right) self.parseTree(c, lans, height, 0, vloc[0]+xSteps, vloc, +xSteps) #self.text(c, "Hello", 10.5, 30,30) for i in self.drawLater: self.drawImage(c, i[0], (i[1], i[2]), True) self.drawImage(c, '/usr/local/tcs/tums/images/vulani-globe-64.png', vloc, True) out = StringIO.StringIO() surface.write_to_png(out) out.seek(0) return render(out.read())
def writeConfig(self, *a): if not config.General.get('ha'): # No Xen config return haConf = config.General.get('ha') nodes = [] masterName = "" for nodeip, v in haConf.items(): nodes.append(v['name']) if v['topology'] == "master": masterName = v['name'] hacf = """logfile /var/log/ha.log keepalive 1 deadtime 30 initdead 80 bcast %(lan)s # Tell what machines are in the cluster # node nodename ... -- must match uname -n node %(node)s # Usualy 'crm yes' #crm respawn auto_failback yes """ % { 'lan': haConf.get('port', Utils.getLans(config)[0]), 'node': ' '.join(nodes) } Utils.writeConf('/etc/heartbeat/ha.cf', hacf, '#') auth = "auth 2\n2 sha1 haf%s\n" % masterName Utils.writeConf('/etc/heartbeat/authkeys', auth, '#') os.system('chmod 0600 /etc/heartbeat/authkeys') nets = [] for k,v in config.EthernetDevices.items(): nets.append('%s/%s' % (v['ip'], k)) conline = "%s %s vulani\n" % (masterName, ' '.join(nets)) Utils.writeConf('/etc/heartbeat/haresources', conline, '#') vulaniResource = """#!/bin/sh # # Description: Vulani Master resource.d # # Author: Colin Alston <*****@*****.**> # Support: [email protected] # License: All rights reserved # Copyright: (C) 2008 Thusa Business Support (Pty) Ltd. exit 0""" l = open('/etc/heartbeat/resource.d/vulani', 'wt') l.write(vulaniResource) l.close() os.system('chmod a+x /etc/heartbeat/resource.d/vulani') # Before we restart our local HB service, make sure our slaves are OFF for name, v in haConf.items(): if v['topology'] == 'slave': os.system('ssh root@%s /etc/init.d/heartbeat stop' % name) os.system('/etc/init.d/heartbeat restart') # Reconfigure SSH to not do SHKC # This is required in order for fresh hosts not to block eachother interactivly ssh_config = """# SSH client configuration Host * StrictHostKeyChecking no SendEnv LANG LC_* HashKnownHosts yes GSSAPIAuthentication yes GSSAPIDelegateCredentials no\n""" Utils.writeConf('/etc/ssh/ssh_config', ssh_config, '#') # Configure master LDAP self.configureMasterLDAP() # Configure slaves for nodeip, v in haConf.items(): if v['topology'] == 'slave': self.configureSlave(nodeip) self.sendLDAP(nodeip)