├── favicon.ico ├── vendor ├── made_mfm.png └── light_noise_diagonal.png ├── .gitattributes ├── README.md ├── config.ini.php ├── LICENSE ├── app.css ├── app.js ├── api.php └── index.php /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/totoCZ/MikroGlass/HEAD/favicon.ico -------------------------------------------------------------------------------- /vendor/made_mfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/totoCZ/MikroGlass/HEAD/vendor/made_mfm.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto -------------------------------------------------------------------------------- /vendor/light_noise_diagonal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/totoCZ/MikroGlass/HEAD/vendor/light_noise_diagonal.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) 2 | [Wiki page](https://github.com/TomHetmer/MikroGlass/wiki) 3 | === 4 | -------------------------------------------------------------------------------- /config.ini.php: -------------------------------------------------------------------------------- 1 | ; Download" 15 | 16 | [login] 17 | user=mguser270114 18 | 19 | ; only for putty link 20 | ; leave empty for ssh on linux 21 | password= 22 | 23 | [servers] 24 | fqdn[0]=193.187.80.16 25 | fqdn[1]=demo.mt.lv 26 | fqdn[2]=demo2.mt.lv 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Tomáš Hetmer 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /app.css: -------------------------------------------------------------------------------- 1 | .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a, .navbar ul li a:hover { 2 | background-image: none; 3 | background-color: #d43f3a; 4 | } 5 | 6 | footer { 7 | border-top: 1px solid #e5e5e5; 8 | color: #777; 9 | padding-top: 19px; 10 | } 11 | 12 | .jumbotron h1 { 13 | color: #d43f3a; 14 | font-family: "Josefin Sans"; 15 | } 16 | 17 | .jumbotron h1 { 18 | font-size: 50px; 19 | } 20 | 21 | .mfm { 22 | height: 50px; 23 | position: absolute; 24 | top: 2px; 25 | right: 40px; 26 | border: 0; 27 | } 28 | 29 | @media (min-width: 768px) { 30 | .mfm { right: 2px; } 31 | } 32 | 33 | 34 | .navbar-nav > .active > a,.navbar-nav > .active > a:hover { 35 | background-color: #d43f3a; 36 | color: #eee; 37 | } 38 | 39 | .ug-navbar { 40 | background-color: #d43f3a; 41 | border-bottom: 3px solid #eee; 42 | color: #FFF; 43 | } 44 | 45 | .ug-navbar a,.ug-navbar li a { 46 | border-top: 3px solid #d43f3a; 47 | color: #FFF; 48 | } 49 | 50 | .ug-navbar a:hover,.ug-navbar li a:hover,.ug-navbar li.active a { 51 | border-top: 3px solid #eee; 52 | color: #eee; 53 | } 54 | 55 | body { 56 | font-family: "Droid Sans"; 57 | background: url('vendor/light_noise_diagonal.png'); 58 | } -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var currentServer = 0; 2 | var currentAction = 'ping'; 3 | 4 | function selectServer(id) { 5 | $('.command').html('Locked on ' + $('.server-' + id).text()); 6 | currentServer = id; 7 | $('.server').removeClass('active'); 8 | $('.server-' + id).addClass('active'); 9 | } 10 | 11 | function quick(type) { 12 | post(currentServer, type); 13 | } 14 | 15 | function switchAction(action) { 16 | prevAction = currentAction; 17 | currentAction = action; 18 | 19 | if (currentAction == 'route' && prevAction != 'route') { 20 | $('#form #fqdn').val(''); 21 | } 22 | if (currentAction != 'route' && prevAction == 'route') { 23 | $('#form #fqdn').val(''); 24 | } 25 | 26 | if (currentAction == 'route') { 27 | $('#btnText').html('BGP Route'); 28 | $('#fqdn').attr('placeholder', 'ip address'); 29 | } else { 30 | $('#fqdn').attr('placeholder', 'ip address or domain name'); 31 | } 32 | 33 | if (currentAction == 'ping') { 34 | $('#btnText').html('Ping IPV4'); 35 | } 36 | 37 | if (currentAction == 'trace') { 38 | $('#btnText').html('Traceroute IPV4'); 39 | } 40 | if (currentAction == 'ping6') { 41 | $('#btnText').html('Ping IPV6'); 42 | } 43 | 44 | if (currentAction == 'trace6') { 45 | $('#btnText').html('Traceroute IPV6'); 46 | } 47 | 48 | if($('#form #fqdn').val() != "") { 49 | post(currentServer, currentAction, $('#form #fqdn').val()); 50 | } 51 | } 52 | 53 | function post(id, type, command) { 54 | $('.command').fadeOut(); 55 | 56 | $.ajax({ 57 | type: 'POST', 58 | url: './api.php', 59 | data: { 60 | id: id, 61 | type: type, 62 | command: command 63 | }, 64 | dataType: 'json', 65 | timeout: 30000, 66 | context: $('body'), 67 | success: function(data) { 68 | if (data.error) 69 | alert('Error: ' + data.error) 70 | else { 71 | $('.command').html(data.command).fadeIn(); 72 | $('.result').prepend(data.result); 73 | $('.result').prepend('

[' + $('.server-' + id).text() + '] ' + data.command + '

'); 74 | } 75 | }, 76 | error: function(xhr, type) { 77 | alert('Failure in API.'); 78 | } 79 | }); 80 | } 81 | 82 | $(document).ready(function() { 83 | 84 | selectServer(0); 85 | 86 | $("#form").submit(function(event) { 87 | event.preventDefault(); 88 | post(currentServer, currentAction, $('#form #fqdn').val()); 89 | }); 90 | 91 | }); -------------------------------------------------------------------------------- /api.php: -------------------------------------------------------------------------------- 1 | . 17 | */ 18 | 19 | header('Content-Type: application/json'); 20 | 21 | function valid_ipv6_address( $ipv6 ) 22 | { 23 | $regex = '/^(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:(?!$)|$)|\2))(?4){5}((?4){2}|(25[0-5]|(2[0-4]|1\d|[1-9])?\d)(\.(?7)){3})\z/i'; 24 | if(!preg_match($regex, $ipv6)) 25 | return (false); // is not a valid IPv6 Address 26 | 27 | return (true); 28 | } 29 | 30 | function fail($why) { 31 | echo json_encode(array( 32 | 'error' => $why 33 | )); 34 | exit(); 35 | } 36 | 37 | $config = parse_ini_file("config.ini.php"); 38 | $user = $config['user']; 39 | $password = $config['password']; 40 | 41 | $tools = array( 42 | 'ping' => '/ping count=5', 43 | 'trace' => '/tool traceroute use-dns=yes duration=3', 44 | 'ping6' => '/ping count=5', 45 | 'trace6' => '/tool traceroute use-dns=yes duration=3', 46 | 'route' => '/ip r pr de where bgp %s in dst-address', 47 | 'ipv4-route-info' => '/ip route print', 48 | 'ipv6-route-info' => '/ipv6 route print', 49 | 'bgp-peer' => '/routing bgp peer print', 50 | //Commented out by default to disallow any chance for users to see BGP peer password details etc 51 | //'bgp-status' => '/routing bgp peer print status', 52 | 'ospf-neighbor' => '/routing ospf neigh print', 53 | 'v4-neighbor' => '/ip neigh pr de', 54 | 'v6-neighbor' => '/ipv6 neigh pr', 55 | ); 56 | 57 | $type = $_POST['type']; // type of command (ping, trace, ..) 58 | $tool = $tools[$type]; // command syntax 59 | $argument = $_POST['command']; // user's argument 60 | $server = $config['fqdn'][$_POST['id']];// resolve FQDN host 61 | $exec = $tool; // simple commands execute immediately 62 | 63 | if (!$tool || !$server) { 64 | // Does not match our tool or server arrays. 65 | fail('Wrong parameters.'); 66 | } 67 | 68 | if ($type == 'ping' || $type == 'trace' || $type == 'ping6' || $type == 'trace6' || $type == 'route') { 69 | // We need argument for these tools 70 | if (empty($argument)) { 71 | fail('Empty parameter.'); 72 | } 73 | 74 | // Need to sanitize IPV4 hostname 75 | if ($type == 'ping' || $type == 'trace' || $type == 'route') { 76 | // check that the argument - is the ip 77 | // if realy ip - ok we are go further 78 | // if not ip - maybe it's hostname? 79 | // get dns A record 80 | if(ip2long($argument)){ 81 | $argument = $argument; 82 | } else { 83 | $host = dns_get_record($argument,DNS_A); 84 | if($host) { 85 | $argument = $host[0][ip]; 86 | } else { 87 | fail('Wrong IPV4 hostname.'); 88 | } 89 | } 90 | } 91 | // Need to sanitize IPV6 hostname 92 | // check that the argument - is the ipv6 93 | // if realy ipv6 - ok we are go further 94 | // if not ip - maybe it's hostname? 95 | // get dns AAAA record 96 | if ($type == 'ping6' || $type == 'trace6') { 97 | // Always returns safely with IP, even for IPs 98 | //$host = gethostbynamel($argument); 99 | if (valid_ipv6_address( $argument )){ 100 | $argument = $argument; 101 | } else { 102 | $host = dns_get_record($argument,DNS_AAAA); 103 | if($host) { 104 | $argument = $host[0][ipv6]; 105 | } else { 106 | fail('Wrong IPV6 hostname.'); 107 | } 108 | } 109 | } 110 | 111 | // BGP route lookup 112 | if ($type == 'route') { 113 | $exec = sprintf($tool, escapeshellcmd($argument)); 114 | }else{ 115 | $exec = $tool . ' ' . escapeshellcmd($argument); 116 | } 117 | } 118 | 119 | // Can't really ssh with passwords 120 | // Key auth works. 121 | if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && empty($config['password'])) { 122 | // Linux, no password/keys, let's ssh 123 | $fp = popen('ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' . $user . '@' . $server . ' ' . $exec, 'r'); 124 | } else { 125 | // Putty Link fallback (Linux, Windows) 126 | $fp = popen($config['path'] . ' -ssh -l ' . $user . ' -pw ' . $password . ' ' . $server . ' ' . $exec, 'r'); 127 | } 128 | 129 | // Handle stream 130 | $out = null; 131 | while (!feof($fp)) { 132 | $out .= fgets($fp); 133 | } 134 | pclose($fp); 135 | 136 | // Return result and our command for display 137 | echo json_encode(array( 138 | 'command' => $exec, 139 | 'result' => $out 140 | )); 141 | ?> 142 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?php echo $c['title'] ?> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 46 | 47 | Fork me on GitHub 48 | 49 |
50 | 51 |
52 |

53 | MikroGlass LG 54 |

55 | 56 | Company logo 57 | 58 |

59 | You have connected to a looking glass server operated by . 60 |

61 | 62 |
63 | 64 | 70 | 71 | 77 | 78 |
79 |
80 |
81 | 84 | 87 | 94 |
95 | 96 |
97 |

98 | Quickcheck: 99 | IPv4 Routes| 100 | IPv6 Routes| 101 | BGP Peers| 102 | Neighbors: 103 | OSPF| 104 | IPv4| 105 | IPv6 106 |

107 |
108 | 109 | 115 | 116 |
Awaiting instructions.
117 | 118 | 123 | 124 |
125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | --------------------------------------------------------------------------------